mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-17 17:58:09 +08:00
feat: enable to find value by recursive search
This commit is contained in:
@@ -12,8 +12,9 @@
|
||||
#include <deque>
|
||||
#include <array>
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_find)
|
||||
BOOST_AUTO_TEST_CASE(test_find_for_value)
|
||||
{
|
||||
// value itself is not a table
|
||||
{
|
||||
toml::value v(true);
|
||||
bool thrown = false;
|
||||
@@ -27,22 +28,87 @@ BOOST_AUTO_TEST_CASE(test_find)
|
||||
}
|
||||
BOOST_CHECK(thrown);
|
||||
}
|
||||
|
||||
// the value corresponding to the key is not the expected type
|
||||
{
|
||||
toml::table v{{"num", 42}};
|
||||
BOOST_CHECK_EQUAL(42, toml::find<int>(v, "num"));
|
||||
toml::find<toml::integer>(v, "num") = 54;
|
||||
BOOST_CHECK_EQUAL(54, toml::find<int>(v, "num"));
|
||||
toml::value v{{"key", 42}};
|
||||
bool thrown = false;
|
||||
try
|
||||
{
|
||||
toml::find<toml::boolean>(v, "key");
|
||||
}
|
||||
catch(toml::type_error const& te)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
BOOST_CHECK(thrown);
|
||||
}
|
||||
|
||||
{
|
||||
toml::value v = toml::table{{"num", 42}};
|
||||
BOOST_CHECK_EQUAL(42, toml::find<int>(v, "num"));
|
||||
toml::find<toml::integer>(v, "num") = 54;
|
||||
|
||||
// reference that can be used to modify the content
|
||||
auto& num = toml::find<toml::integer>(v, "num");
|
||||
num = 54;
|
||||
BOOST_CHECK_EQUAL(54, toml::find<int>(v, "num"));
|
||||
}
|
||||
|
||||
// recursively search tables
|
||||
{
|
||||
toml::value v = toml::table{
|
||||
{"a", toml::table{
|
||||
{"b", toml::table{
|
||||
{"c", toml::table{
|
||||
{"d", 42}
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
};
|
||||
BOOST_CHECK_EQUAL(42, toml::find<int>(v, "a", "b", "c", "d"));
|
||||
|
||||
// reference that can be used to modify the content
|
||||
auto& num = toml::find<toml::integer>(v, "a", "b", "c", "d");
|
||||
num = 54;
|
||||
BOOST_CHECK_EQUAL(54, toml::find<int>(v, "a", "b", "c", "d"));
|
||||
|
||||
const std::string a("a"), b("b"), c("c"), d("d");
|
||||
auto& num2 = toml::find<toml::integer>(v, a, b, c, d);
|
||||
num2 = 42;
|
||||
BOOST_CHECK_EQUAL(42, toml::find<int>(v, a, b, c, d));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_find_for_table)
|
||||
{
|
||||
// the value corresponding to the key is not the expected type
|
||||
{
|
||||
toml::table v{{"key", 42}};
|
||||
bool thrown = false;
|
||||
try
|
||||
{
|
||||
toml::find<toml::boolean>(v, "key");
|
||||
}
|
||||
catch(toml::type_error const& te)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
BOOST_CHECK(thrown);
|
||||
}
|
||||
|
||||
{
|
||||
toml::table v{{"num", 42}};
|
||||
BOOST_CHECK_EQUAL(42, toml::find<int>(v, "num"));
|
||||
|
||||
// reference that can be used to modify the content
|
||||
auto& num = toml::find<toml::integer>(v, "num");
|
||||
num = 54;
|
||||
BOOST_CHECK_EQUAL(54, toml::find<int>(v, "num"));
|
||||
}
|
||||
|
||||
// recursive search is not provided for tables.
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_get_or)
|
||||
{
|
||||
// requires conversion int -> uint
|
||||
|
26
toml/get.hpp
26
toml/get.hpp
@@ -430,6 +430,32 @@ find(toml::value&& v, const toml::key& ky)
|
||||
return ::toml::get<T>(std::move(tab[ky]));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// toml::find(toml::value, toml::key, Ts&& ... keys)
|
||||
//
|
||||
// Note: C++ draft N3337 (14.1.11) says that...
|
||||
// > If a template-parameter of a class template or alias template has a default
|
||||
// > template-argument, each subsequent template-parameter shall either have a
|
||||
// > default template-argument supplied or be a template parameter pack.
|
||||
// So the template parameter pack can appear after a default template argument.
|
||||
template<typename T = ::toml::value, typename ... Ts>
|
||||
decltype(::toml::get<T>(std::declval<const ::toml::value&>()))
|
||||
find(const ::toml::value& v, const ::toml::key& ky, Ts&& ... keys)
|
||||
{
|
||||
return ::toml::find<T>(::toml::find(v, ky), std::forward<Ts>(keys)...);
|
||||
}
|
||||
template<typename T = ::toml::value, typename ... Ts>
|
||||
decltype(::toml::get<T>(std::declval<::toml::value&>()))
|
||||
find(::toml::value& v, const ::toml::key& ky, Ts&& ... keys)
|
||||
{
|
||||
return ::toml::find<T>(::toml::find(v, ky), std::forward<Ts>(keys)...);
|
||||
}
|
||||
template<typename T = ::toml::value, typename ... Ts>
|
||||
decltype(::toml::get<T>(std::declval<::toml::value&&>()))
|
||||
find(::toml::value&& v, const ::toml::key& ky, Ts&& ... keys)
|
||||
{
|
||||
return ::toml::find<T>(::toml::find(std::move(v), ky), std::forward<Ts>(keys)...);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// get_or(value, fallback)
|
||||
|
Reference in New Issue
Block a user