mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-17 00:38:08 +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)
|
||||
{
|
||||
{
|
||||
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));
|
||||
}
|
||||
// requires conversion int -> uint
|
||||
{
|
||||
toml::value v1(42);
|
||||
toml::value v2(3.14);
|
||||
BOOST_CHECK_EQUAL(42, toml::get_or<int>(v1, 0));
|
||||
BOOST_CHECK_EQUAL(0, toml::get_or<int>(v2, 0));
|
||||
BOOST_CHECK_EQUAL(42u, toml::get_or(v1, 0u));
|
||||
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<
|
||||
typename std::remove_reference<T>::type>::type>(
|
||||
std::declval<const toml::value&>()))
|
||||
get_or(const toml::value& v, T&& opt)
|
||||
// ----------------------------------------------------------------------------
|
||||
// specialization for the exact toml types (return type becomes lvalue ref)
|
||||
|
||||
template<typename T, typename std::enable_if<
|
||||
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||
T const& get_or(const toml::value& v, const T& opt)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -435,14 +436,12 @@ get_or(const toml::value& v, T&& opt)
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return std::forward<T>(opt);
|
||||
return opt;
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
decltype(::toml::get<typename std::remove_cv<
|
||||
typename std::remove_reference<T>::type>::type>(
|
||||
std::declval<toml::value&>()))
|
||||
get_or(toml::value& v, T&& opt)
|
||||
template<typename T, typename std::enable_if<
|
||||
detail::is_exact_toml_type<T>::value, std::nullptr_t>::type = nullptr>
|
||||
T& get_or(toml::value& v, T& opt)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -451,77 +450,333 @@ get_or(toml::value& v, T&& opt)
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return std::forward<T>(opt);
|
||||
return opt;
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
decltype(::toml::get<typename std::remove_cv<
|
||||
typename std::remove_reference<T>::type>::type>(
|
||||
std::declval<toml::value&&>()))
|
||||
get_or(toml::value&& v, T&& opt)
|
||||
template<typename T, typename std::enable_if<
|
||||
detail::is_exact_toml_type<T>::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>(std::move(v));
|
||||
typename std::remove_reference<T>::type>::type>(v);
|
||||
}
|
||||
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>
|
||||
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)
|
||||
-> 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));
|
||||
}
|
||||
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)
|
||||
-> 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));
|
||||
}
|
||||
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)
|
||||
-> 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));
|
||||
}
|
||||
|
||||
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)
|
||||
-> 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);
|
||||
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));
|
||||
}
|
||||
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)
|
||||
-> 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);
|
||||
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));
|
||||
}
|
||||
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)
|
||||
-> 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));
|
||||
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));
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// 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
|
||||
|
||||
|
@@ -169,6 +169,21 @@ using return_type_of_t = typename std::result_of<F(Args...)>::type;
|
||||
|
||||
#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
|
||||
}//toml
|
||||
#endif // TOML_TRAITS
|
||||
|
@@ -8,11 +8,11 @@
|
||||
#include <sstream>
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
# define TOML11_MARK_AS_DEPRECATED [[deprecated]]
|
||||
# define TOML11_MARK_AS_DEPRECATED(msg) [[deprecated(msg)]]
|
||||
#elif defined(__GNUC__)
|
||||
# define TOML11_MARK_AS_DEPRECATED __attribute__((deprecated))
|
||||
# define TOML11_MARK_AS_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#elif defined(_MSC_VER)
|
||||
# define TOML11_MARK_AS_DEPRECATED __declspec(deprecated)
|
||||
# define TOML11_MARK_AS_DEPRECATED(msg) __declspec(deprecated(msg))
|
||||
#else
|
||||
# define TOML11_MARK_AS_DEPRECATED
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user