diff options
Diffstat (limited to 'host')
-rw-r--r-- | host/include/uhd/property_tree.hpp | 7 | ||||
-rw-r--r-- | host/include/uhd/property_tree.ipp | 6 | ||||
-rw-r--r-- | host/lib/property_tree.cpp | 23 | ||||
-rw-r--r-- | host/tests/property_test.cpp | 8 |
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")); |