Merge pull request #5922 from bska/property-tree-get-children-as-vector

Add Property Tree Array Retrieval Mechanism
This commit is contained in:
Bård Skaflestad 2025-01-29 17:01:07 +01:00 committed by GitHub
commit aa5c52ee56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 76 additions and 0 deletions

View File

@ -28,6 +28,7 @@
#include <optional> #include <optional>
#include <ostream> #include <ostream>
#include <string> #include <string>
#include <vector>
namespace Opm { namespace Opm {
@ -95,6 +96,25 @@ PropertyTree::get_child_optional(const std::string& key) const
return PropertyTree(pt.get()); return PropertyTree(pt.get());
} }
template <typename T>
std::optional<std::vector<T>>
PropertyTree::get_child_items_as_vector(const std::string& child) const
{
auto items = std::optional<std::vector<T>>{};
auto subTree = this->tree_->get_child_optional(child);
if (! subTree) {
return items;
}
items.emplace();
for (const auto& childItem : *subTree) {
items->push_back(childItem.second.template get_value<T>());
}
return items;
}
PropertyTree& PropertyTree::operator=(const PropertyTree& tree) PropertyTree& PropertyTree::operator=(const PropertyTree& tree)
{ {
tree_ = std::make_unique<boost::property_tree::ptree>(*tree.tree_); tree_ = std::make_unique<boost::property_tree::ptree>(*tree.tree_);
@ -121,4 +141,9 @@ template int PropertyTree::get(const std::string& key, const int& defValue) cons
template std::size_t PropertyTree::get(const std::string& key, const std::size_t& defValue) const; template std::size_t PropertyTree::get(const std::string& key, const std::size_t& defValue) const;
template bool PropertyTree::get(const std::string& key, const bool& defValue) const; template bool PropertyTree::get(const std::string& key, const bool& defValue) const;
template std::optional<std::vector<int>>
PropertyTree::get_child_items_as_vector(const std::string& child) const;
template std::optional<std::vector<double>>
PropertyTree::get_child_items_as_vector(const std::string& child) const;
} // namespace Opm } // namespace Opm

View File

@ -25,6 +25,7 @@
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <string> #include <string>
#include <vector>
namespace boost::property_tree { namespace boost::property_tree {
template<class T1, class T2, class T3> class basic_ptree; template<class T1, class T2, class T3> class basic_ptree;
@ -128,6 +129,23 @@ public:
std::optional<PropertyTree> std::optional<PropertyTree>
get_child_optional(const std::string& key) const; get_child_optional(const std::string& key) const;
/// Retrieve node items as linearised vector.
///
/// Assumes that the node's child is an array type of homongeneous
/// elements.
///
/// \tparam T Array element type.
///
/// \param[in] child Property key. Expected to be in hierarchical
/// notation for subtrees--i.e., using periods ('.') to separate
/// hierarchy levels.
///
/// \return Array of property values. Nullopt if no node named by \p
/// child exists.
template <typename T>
std::optional<std::vector<T>>
get_child_items_as_vector(const std::string& child) const;
/// Emit a textual representation of the property tree in JSON form /// Emit a textual representation of the property tree in JSON form
/// ///
/// \param[in,out] os Output stream. Typically a stream opened on a /// \param[in,out] os Output stream. Typically a stream opened on a

View File

@ -259,4 +259,37 @@ BOOST_AUTO_TEST_CASE(Hierarchy)
} }
} }
BOOST_AUTO_TEST_CASE(Vector)
{
auto f = TempFile{};
f.append(R"({
"a" : [ 1, 2, 3, 4 ],
"b" : [ 11.22, 33.44 ]
})");
const auto t = Opm::PropertyTree { f.name() };
{
const auto a = t.get_child_items_as_vector<int>("a");
BOOST_REQUIRE_MESSAGE(a.has_value(), R"(Node "a" must exist)");
const auto expect = std::vector { 1, 2, 3, 4, };
BOOST_CHECK_EQUAL_COLLECTIONS(a ->begin(), a ->end(),
expect.begin(), expect.end());
}
{
const auto b = t.get_child_items_as_vector<double>("b");
BOOST_REQUIRE_MESSAGE(b.has_value(), R"(Node "b" must exist)");
const auto expect = std::vector { 11.22, 33.44, };
BOOST_REQUIRE_EQUAL(b->size(), expect.size());
for (auto i = 0*b->size(); i < b->size(); ++i) {
BOOST_TEST_MESSAGE("Element " << i);
BOOST_CHECK_CLOSE((*b)[i], expect[i], 1.0e-8);
}
}
}
BOOST_AUTO_TEST_SUITE_END() // Load_From_File BOOST_AUTO_TEST_SUITE_END() // Load_From_File