aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrent Stapleton <brent.stapleton@ettus.com>2019-04-11 11:36:31 -0700
committerMartin Braun <martin.braun@ettus.com>2019-05-02 08:39:54 -0700
commit01fd6d52cefdb2baa7070b91ed483e9456141966 (patch)
treef43dae9b6291c28108b3896641374d643c7c8ca4
parentd44277d7ac7acc621442fe7ef4555f568fbe88d0 (diff)
downloaduhd-01fd6d52cefdb2baa7070b91ed483e9456141966.tar.gz
uhd-01fd6d52cefdb2baa7070b91ed483e9456141966.tar.bz2
uhd-01fd6d52cefdb2baa7070b91ed483e9456141966.zip
prop_tree: add pop() function
Adding pop function to property tree, which will remove and return a property from the property tree. This also includes unit tests.
-rw-r--r--host/include/uhd/property_tree.hpp7
-rw-r--r--host/include/uhd/property_tree.ipp6
-rw-r--r--host/lib/property_tree.cpp23
-rw-r--r--host/tests/property_test.cpp8
4 files changed, 44 insertions, 0 deletions
diff --git a/host/include/uhd/property_tree.hpp b/host/include/uhd/property_tree.hpp
index 42e73458f..11b92393a 100644
--- a/host/include/uhd/property_tree.hpp
+++ b/host/include/uhd/property_tree.hpp
@@ -243,7 +243,14 @@ public:
template <typename T>
property<T>& access(const fs_path& path);
+ //! Pop a property off the tree, and returns the property
+ template <typename T>
+ boost::shared_ptr<property<T> > pop(const fs_path& path);
+
private:
+ //! Internal pop function
+ virtual boost::shared_ptr<void> _pop(const fs_path& path) = 0;
+
//! Internal create property with wild-card type
virtual void _create(const fs_path& path, const boost::shared_ptr<void>& prop) = 0;
diff --git a/host/include/uhd/property_tree.ipp b/host/include/uhd/property_tree.ipp
index de1ac28c0..ca5d6904f 100644
--- a/host/include/uhd/property_tree.ipp
+++ b/host/include/uhd/property_tree.ipp
@@ -192,6 +192,12 @@ property<T>& property_tree::access(const fs_path& path)
return *boost::static_pointer_cast<property<T> >(this->_access(path));
}
+template <typename T>
+typename boost::shared_ptr<property<T> > property_tree::pop(const fs_path& path)
+{
+ return boost::static_pointer_cast<property<T> >(this->_pop(path));
+}
+
} // namespace uhd
#endif /* INCLUDED_UHD_PROPERTY_TREE_IPP */
diff --git a/host/lib/property_tree.cpp b/host/lib/property_tree.cpp
index 07da0cf59..85868b27c 100644
--- a/host/lib/property_tree.cpp
+++ b/host/lib/property_tree.cpp
@@ -133,6 +133,29 @@ public:
return node->keys();
}
+ boost::shared_ptr<void> _pop(const fs_path& path_)
+ {
+ const fs_path path = _root / path_;
+ boost::mutex::scoped_lock lock(_guts->mutex);
+
+ node_type* parent = NULL;
+ node_type* node = &_guts->root;
+ for (const std::string& name : path_tokenizer(path)) {
+ if (not node->has_key(name))
+ throw_path_not_found(path);
+ parent = node;
+ node = &(*node)[name];
+ }
+
+ if (node->prop.get() == NULL)
+ throw uhd::runtime_error("Cannot access! Property uninitialized at: " + path);
+ if (parent == NULL)
+ throw uhd::runtime_error("Cannot pop");
+ auto prop = node->prop;
+ parent->pop(fs_path(path.leaf()));
+ return prop;
+ }
+
void _create(const fs_path& path_, const boost::shared_ptr<void>& prop)
{
const fs_path path = _root / path_;
diff --git a/host/tests/property_test.cpp b/host/tests/property_test.cpp
index f0e67e14c..907ca9f73 100644
--- a/host/tests/property_test.cpp
+++ b/host/tests/property_test.cpp
@@ -192,6 +192,7 @@ BOOST_AUTO_TEST_CASE(test_prop_tree)
tree->create<int>("/test/prop0");
tree->create<int>("/test/prop1");
+ tree->create<int>("/test/prop2");
BOOST_CHECK(tree->exists("/test"));
BOOST_CHECK_THROW(tree->access<int>("/test"), std::exception);
@@ -200,6 +201,7 @@ BOOST_AUTO_TEST_CASE(test_prop_tree)
tree->access<int>("/test/prop0").set(42);
tree->access<int>("/test/prop1").set(34);
+ tree->access<int>("/test/prop2").set(107);
BOOST_CHECK_EQUAL(tree->access<int>("/test/prop0").get(), 42);
BOOST_CHECK_EQUAL(tree->access<int>("/test/prop1").get(), 34);
@@ -208,6 +210,12 @@ BOOST_AUTO_TEST_CASE(test_prop_tree)
BOOST_CHECK(not tree->exists("/test/prop0"));
BOOST_CHECK(tree->exists("/test/prop1"));
+ const uhd::fs_path prop_path = "/test/prop2";
+ auto prop_sptr = tree->pop<int>(prop_path);
+ BOOST_CHECK(not tree->exists("/test/prop2"));
+ BOOST_CHECK(tree->exists("/test/prop1"));
+ BOOST_CHECK(prop_sptr->get() == 107);
+
tree->remove("/test");
BOOST_CHECK(not tree->exists("/test/prop0"));
BOOST_CHECK(not tree->exists("/test/prop1"));