mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-17 17:58:09 +08:00
Merge pull request #45 from ToruNiina/get_or
fix `get_or` and add `find_or`
This commit is contained in:
@@ -45,21 +45,194 @@ BOOST_AUTO_TEST_CASE(test_find)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_or)
|
BOOST_AUTO_TEST_CASE(test_get_or)
|
||||||
{
|
{
|
||||||
{
|
// requires conversion int -> uint
|
||||||
toml::table v{{"num", 42}};
|
|
||||||
BOOST_CHECK_EQUAL(42, toml::get_or<int>(v, "num", 0));
|
|
||||||
BOOST_CHECK_EQUAL(0, toml::get_or<int>(v, "foo", 0));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
toml::value v = toml::table{{"num", 42}};
|
|
||||||
BOOST_CHECK_EQUAL(42, toml::get_or<int>(v, "num", 0));
|
|
||||||
BOOST_CHECK_EQUAL(0, toml::get_or<int>(v, "foo", 0));
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
|
toml::integer opt(0);
|
||||||
|
BOOST_CHECK_EQUAL(42, toml::get_or(v1, opt));
|
||||||
|
BOOST_CHECK_EQUAL(0, toml::get_or(v2, opt));
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_find_or)
|
||||||
|
{
|
||||||
|
// ========================================================================
|
||||||
|
// pass toml::value
|
||||||
|
//
|
||||||
|
// requires conversion int -> uint
|
||||||
|
{
|
||||||
|
toml::table v{{"num", 42}};
|
||||||
|
BOOST_CHECK_EQUAL(42u, toml::find_or(v, "num", 0u));
|
||||||
|
BOOST_CHECK_EQUAL(0u, toml::find_or(v, "foo", 0u));
|
||||||
|
}
|
||||||
|
// exact toml type
|
||||||
|
{
|
||||||
|
toml::table v1{{"key", 42 }};
|
||||||
|
toml::table v2{{"key", 3.14}};
|
||||||
|
toml::table v3{{"not", "key"}};
|
||||||
|
|
||||||
|
toml::integer opt(0);
|
||||||
|
BOOST_CHECK_EQUAL(42, toml::find_or(v1, "key", opt));
|
||||||
|
BOOST_CHECK_EQUAL(0, toml::find_or(v2, "key", opt));
|
||||||
|
BOOST_CHECK_EQUAL(0, toml::find_or(v3, "key", opt));
|
||||||
|
|
||||||
|
toml::table v4{{"str", "foobar"}};
|
||||||
|
toml::string s("bazqux");
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v4, "str", s));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v1, "str", s));
|
||||||
|
}
|
||||||
|
// std::string
|
||||||
|
{
|
||||||
|
toml::table v1{{"key", "foobar"}};
|
||||||
|
toml::table v2{{"key", 42}};
|
||||||
|
|
||||||
|
std::string s1("bazqux");
|
||||||
|
const std::string s2("bazqux");
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", s1));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", s1));
|
||||||
|
|
||||||
|
std::string& v1r = toml::find_or(v1, "key", s1);
|
||||||
|
std::string& s1r = toml::find_or(v2, "key", s1);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", v1r);
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", s1r);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", s2));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", s2));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(std::move(v1), "key", std::move(s1)));
|
||||||
|
s1 = "bazqux"; // restoring moved value
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(std::move(v2), "key", std::move(s1)));
|
||||||
|
}
|
||||||
|
// string literal
|
||||||
|
{
|
||||||
|
toml::table v1{{"key", "foobar"}};
|
||||||
|
toml::table v2{{"key",42}};
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", "bazqux"));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", "bazqux"));
|
||||||
|
|
||||||
|
const char* lit = "bazqux";
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", lit));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", lit));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================================================
|
||||||
|
// pass toml::value
|
||||||
|
//
|
||||||
|
// requires conversion int -> uint
|
||||||
|
{
|
||||||
|
toml::table v = toml::table{{"num", 42}};
|
||||||
|
BOOST_CHECK_EQUAL(42u, toml::find_or(v, "num", 0u));
|
||||||
|
BOOST_CHECK_EQUAL(0u, toml::find_or(v, "foo", 0u));
|
||||||
|
}
|
||||||
|
// exact toml type
|
||||||
|
{
|
||||||
|
toml::value v1 = toml::table{{"key", 42 }};
|
||||||
|
toml::value v2 = toml::table{{"key", 3.14}};
|
||||||
|
toml::value v3 = toml::table{{"not", "key"}};
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(42, toml::find_or(v1, "key", toml::integer(0)));
|
||||||
|
BOOST_CHECK_EQUAL( 0, toml::find_or(v2, "key", toml::integer(0)));
|
||||||
|
BOOST_CHECK_EQUAL( 0, toml::find_or(v3, "key", toml::integer(0)));
|
||||||
|
|
||||||
|
toml::value v4 = toml::table{{"str", "foobar"}};
|
||||||
|
toml::string s("bazqux");
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v4, "str", s));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v1, "str", s));
|
||||||
|
}
|
||||||
|
// std::string
|
||||||
|
{
|
||||||
|
toml::value v1 = toml::table{{"key", "foobar"}};
|
||||||
|
toml::value v2 = toml::table{{"key", 42}};
|
||||||
|
|
||||||
|
std::string s1("bazqux");
|
||||||
|
const std::string s2("bazqux");
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", s1));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", s1));
|
||||||
|
|
||||||
|
std::string& v1r = toml::find_or(v1, "key", s1);
|
||||||
|
std::string& s1r = toml::find_or(v2, "key", s1);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", v1r);
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", s1r);
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", s2));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", s2));
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(std::move(v1), "key", std::move(s1)));
|
||||||
|
s1 = "bazqux"; // restoring moved value
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(std::move(v2), "key", std::move(s1)));
|
||||||
|
}
|
||||||
|
// string literal
|
||||||
|
{
|
||||||
|
toml::value v1 = toml::table{{"key", "foobar"}};
|
||||||
|
toml::value v2 = toml::table{{"key",42}};
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", "bazqux"));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", "bazqux"));
|
||||||
|
|
||||||
|
const char* lit = "bazqux";
|
||||||
|
BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", lit));
|
||||||
|
BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", lit));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
313
toml/get.hpp
313
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,77 +450,333 @@ 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// get_or(table, key, fallback)
|
||||||
|
//
|
||||||
|
// DEPRECATED: use find_or instead.
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
TOML11_MARK_AS_DEPRECATED("use toml::find_or(table, key, opt) instead.")
|
||||||
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)
|
||||||
-> decltype(get_or(std::declval<value const&>(), std::forward<T>(opt)))
|
-> decltype(get_or(std::declval<value const&>(), std::forward<T>(opt)))
|
||||||
{
|
{
|
||||||
if(tab.count(ky) == 0) {return std::forward<T>(opt);}
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
return ::toml::get_or(tab.at(ky), std::forward<T>(opt));
|
return ::toml::get_or(tab.at(ky), std::forward<T>(opt));
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
TOML11_MARK_AS_DEPRECATED("use toml::find_or(table, key, opt) instead.")
|
||||||
auto get_or(toml::table& tab, const toml::key& ky, T&& opt)
|
auto get_or(toml::table& tab, const toml::key& ky, T&& opt)
|
||||||
-> decltype(get_or(std::declval<value&>(), std::forward<T>(opt)))
|
-> decltype(get_or(std::declval<value&>(), std::forward<T>(opt)))
|
||||||
{
|
{
|
||||||
if(tab.count(ky) == 0) {return std::forward<T>(opt);}
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
return ::toml::get_or(tab[ky], std::forward<T>(opt));
|
return ::toml::get_or(tab[ky], std::forward<T>(opt));
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
TOML11_MARK_AS_DEPRECATED("use toml::find_or(table, key, opt) instead.")
|
||||||
auto get_or(toml::table&& tab, const toml::key& ky, T&& opt)
|
auto get_or(toml::table&& tab, const toml::key& ky, T&& opt)
|
||||||
-> decltype(get_or(std::declval<value&&>(), std::forward<T>(opt)))
|
-> decltype(get_or(std::declval<value&&>(), std::forward<T>(opt)))
|
||||||
{
|
{
|
||||||
if(tab.count(ky) == 0) {return std::forward<T>(opt);}
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
return ::toml::get_or(std::move(tab[ky]), std::forward<T>(opt));
|
return ::toml::get_or(std::move(tab[ky]), std::forward<T>(opt));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
TOML11_MARK_AS_DEPRECATED("use toml::find_or(value, key, opt) instead.")
|
||||||
auto get_or(const toml::value& v, const toml::key& ky, T&& opt)
|
auto get_or(const toml::value& v, const toml::key& ky, T&& opt)
|
||||||
-> decltype(get_or(std::declval<value const&>(), std::forward<T>(opt)))
|
-> decltype(get_or(std::declval<value const&>(), std::forward<T>(opt)))
|
||||||
{
|
{
|
||||||
if(v.type() != toml::value_t::Table){return std::forward<T>(opt);}
|
if(!v.is_table()) {return opt;}
|
||||||
const auto& tab = toml::get<toml::table>(v);
|
const auto& tab = toml::get<toml::table>(v);
|
||||||
if(tab.count(ky) == 0) {return std::forward<T>(opt);}
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
return ::toml::get_or(tab.at(ky), std::forward<T>(opt));
|
return ::toml::get_or(tab.at(ky), std::forward<T>(opt));
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
TOML11_MARK_AS_DEPRECATED("use toml::find_or(value, key, opt) instead.")
|
||||||
auto get_or(toml::value& v, const toml::key& ky, T&& opt)
|
auto get_or(toml::value& v, const toml::key& ky, T&& opt)
|
||||||
-> decltype(get_or(std::declval<value&>(), std::forward<T>(opt)))
|
-> decltype(get_or(std::declval<value&>(), std::forward<T>(opt)))
|
||||||
{
|
{
|
||||||
if(v.type() != toml::value_t::Table){return std::forward<T>(opt);}
|
if(!v.is_table()) {return opt;}
|
||||||
auto& tab = toml::get<toml::table>(v);
|
auto& tab = toml::get<toml::table>(v);
|
||||||
if(tab.count(ky) == 0) {return std::forward<T>(opt);}
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
return ::toml::get_or(tab[ky], std::forward<T>(opt));
|
return ::toml::get_or(tab[ky], std::forward<T>(opt));
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
TOML11_MARK_AS_DEPRECATED("use toml::find_or(value, key, opt) instead.")
|
||||||
auto get_or(toml::value&& v, const toml::key& ky, T&& opt)
|
auto get_or(toml::value&& v, const toml::key& ky, T&& opt)
|
||||||
-> decltype(get_or(std::declval<value&&>(), std::forward<T>(opt)))
|
-> decltype(get_or(std::declval<value&&>(), std::forward<T>(opt)))
|
||||||
{
|
{
|
||||||
if(v.type() != toml::value_t::Table){return std::forward<T>(opt);}
|
if(!v.is_table()) {return opt;}
|
||||||
auto tab = toml::get<toml::table>(std::move(v));
|
auto tab = toml::get<toml::table>(std::move(v));
|
||||||
if(tab.count(ky) == 0) {return std::forward<T>(opt);}
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
return ::toml::get_or(std::move(tab[ky]), std::forward<T>(opt));
|
return ::toml::get_or(std::move(tab[ky]), std::forward<T>(opt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// find_or(value, key, fallback)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// exact types (return type can be a reference)
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T const& find_or(const toml::value& v, const toml::key& ky, const T& opt)
|
||||||
|
{
|
||||||
|
if(!v.is_table()) {return opt;}
|
||||||
|
const auto& tab = toml::get<toml::table>(v);
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab.at(ky), opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T& find_or(toml::value& v, const toml::key& ky, T& opt)
|
||||||
|
{
|
||||||
|
if(!v.is_table()) {return opt;}
|
||||||
|
auto& tab = toml::get<toml::table>(v);
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab[ky], opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T&& find_or(toml::value&& v, const toml::key& ky, T&& opt)
|
||||||
|
{
|
||||||
|
if(!v.is_table()) {return opt;}
|
||||||
|
auto tab = toml::get<toml::table>(std::move(v));
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(std::move(tab[ky]), std::forward<T>(opt));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// std::string (return type can be a reference)
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
std::is_same<T, std::string>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
std::string const& find_or(const toml::value& v, const toml::key& ky, const T& opt)
|
||||||
|
{
|
||||||
|
if(!v.is_table()) {return opt;}
|
||||||
|
const auto& tab = toml::get<toml::table>(v);
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab.at(ky), opt);
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
std::is_same<T, std::string>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
std::string& find_or(toml::value& v, const toml::key& ky, T& opt)
|
||||||
|
{
|
||||||
|
if(!v.is_table()) {return opt;}
|
||||||
|
auto& tab = toml::get<toml::table>(v);
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab[ky], opt);
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
std::is_same<T, std::string>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
std::string find_or(toml::value&& v, const toml::key& ky, T&& opt)
|
||||||
|
{
|
||||||
|
if(!v.is_table()) {return opt;}
|
||||||
|
auto tab = toml::get<toml::table>(std::move(v));
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(std::move(tab[ky]), std::forward<T>(opt));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// string literal (deduced as std::string)
|
||||||
|
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 find_or(const toml::value& v, const toml::key& ky, T&& opt)
|
||||||
|
{
|
||||||
|
if(!v.is_table()) {return opt;}
|
||||||
|
const auto& tab = toml::get<toml::table>(v);
|
||||||
|
if(tab.count(ky) == 0) {return std::string(opt);}
|
||||||
|
return get_or(tab.at(ky), std::forward<T>(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 find_or(const toml::value& v, const toml::key& ky, T&& opt)
|
||||||
|
{
|
||||||
|
if(!v.is_table()) {return opt;}
|
||||||
|
const auto& tab = toml::get<toml::table>(v);
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab.at(ky), std::forward<T>(opt));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// find_or(table, key, opt)
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// exact types (return type can be a reference)
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T const& find_or(const toml::table& tab, const toml::key& ky, const T& opt)
|
||||||
|
{
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab.at(ky), opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T& find_or(toml::table& tab, const toml::key& ky, T& opt)
|
||||||
|
{
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab[ky], opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
T&& find_or(toml::table&& tab, const toml::key& ky, T&& opt)
|
||||||
|
{
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(std::move(tab[ky]), std::forward<T>(opt));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// std::string (return type can be a reference)
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
std::is_same<T, std::string>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
std::string const& find_or(const toml::table& tab, const toml::key& ky, const T& opt)
|
||||||
|
{
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab.at(ky), opt);
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
std::is_same<T, std::string>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
std::string& find_or(toml::table& tab, const toml::key& ky, T& opt)
|
||||||
|
{
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab[ky], opt);
|
||||||
|
}
|
||||||
|
template<typename T, typename std::enable_if<
|
||||||
|
std::is_same<T, std::string>::value, std::nullptr_t>::type = nullptr>
|
||||||
|
std::string find_or(toml::table&& tab, const toml::key& ky, T&& opt)
|
||||||
|
{
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(std::move(tab[ky]), std::forward<T>(opt));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// string literal (deduced as std::string)
|
||||||
|
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 find_or(const toml::table& tab, const toml::key& ky, T&& opt)
|
||||||
|
{
|
||||||
|
if(tab.count(ky) == 0) {return std::string(opt);}
|
||||||
|
return get_or(tab.at(ky), std::forward<T>(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 find_or(const toml::table& tab, const toml::key& ky, T&& opt)
|
||||||
|
{
|
||||||
|
if(tab.count(ky) == 0) {return opt;}
|
||||||
|
return get_or(tab.at(ky), std::forward<T>(opt));
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// expect
|
// expect
|
||||||
|
|
||||||
|
@@ -169,6 +169,21 @@ using return_type_of_t = typename std::result_of<F(Args...)>::type;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// is_string_literal
|
||||||
|
//
|
||||||
|
// to use this, pass `typename remove_reference<T>::type` to T.
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_string_literal:
|
||||||
|
disjunction<
|
||||||
|
std::is_same<const char*, T>,
|
||||||
|
conjunction<
|
||||||
|
std::is_array<T>,
|
||||||
|
std::is_same<const char, typename std::remove_extent<T>::type>
|
||||||
|
>
|
||||||
|
>{};
|
||||||
|
|
||||||
}// detail
|
}// detail
|
||||||
}//toml
|
}//toml
|
||||||
#endif // TOML_TRAITS
|
#endif // TOML_TRAITS
|
||||||
|
@@ -8,11 +8,11 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#if __cplusplus >= 201402L
|
#if __cplusplus >= 201402L
|
||||||
# define TOML11_MARK_AS_DEPRECATED [[deprecated]]
|
# define TOML11_MARK_AS_DEPRECATED(msg) [[deprecated(msg)]]
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
# define TOML11_MARK_AS_DEPRECATED __attribute__((deprecated))
|
# define TOML11_MARK_AS_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
# define TOML11_MARK_AS_DEPRECATED __declspec(deprecated)
|
# define TOML11_MARK_AS_DEPRECATED(msg) __declspec(deprecated(msg))
|
||||||
#else
|
#else
|
||||||
# define TOML11_MARK_AS_DEPRECATED
|
# define TOML11_MARK_AS_DEPRECATED
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user