mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-09-18 02:08:09 +08:00
feat: enable to find value by recursive search
This commit is contained in:
@@ -12,8 +12,9 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <array>
|
#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);
|
toml::value v(true);
|
||||||
bool thrown = false;
|
bool thrown = false;
|
||||||
@@ -27,22 +28,87 @@ BOOST_AUTO_TEST_CASE(test_find)
|
|||||||
}
|
}
|
||||||
BOOST_CHECK(thrown);
|
BOOST_CHECK(thrown);
|
||||||
}
|
}
|
||||||
|
// the value corresponding to the key is not the expected type
|
||||||
{
|
{
|
||||||
toml::table v{{"num", 42}};
|
toml::value v{{"key", 42}};
|
||||||
BOOST_CHECK_EQUAL(42, toml::find<int>(v, "num"));
|
bool thrown = false;
|
||||||
toml::find<toml::integer>(v, "num") = 54;
|
try
|
||||||
BOOST_CHECK_EQUAL(54, toml::find<int>(v, "num"));
|
{
|
||||||
|
toml::find<toml::boolean>(v, "key");
|
||||||
|
}
|
||||||
|
catch(toml::type_error const& te)
|
||||||
|
{
|
||||||
|
thrown = true;
|
||||||
|
}
|
||||||
|
BOOST_CHECK(thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
toml::value v = toml::table{{"num", 42}};
|
toml::value v = toml::table{{"num", 42}};
|
||||||
BOOST_CHECK_EQUAL(42, toml::find<int>(v, "num"));
|
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"));
|
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)
|
BOOST_AUTO_TEST_CASE(test_get_or)
|
||||||
{
|
{
|
||||||
// requires conversion int -> uint
|
// 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]));
|
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)
|
// get_or(value, fallback)
|
||||||
|
Reference in New Issue
Block a user