aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/include/uhd/property_tree.hpp9
-rw-r--r--host/include/uhd/property_tree.ipp22
-rw-r--r--host/lib/property_tree.cpp7
-rw-r--r--host/tests/property_test.cpp86
4 files changed, 79 insertions, 45 deletions
diff --git a/host/include/uhd/property_tree.hpp b/host/include/uhd/property_tree.hpp
index 630e86bba..63cd76a56 100644
--- a/host/include/uhd/property_tree.hpp
+++ b/host/include/uhd/property_tree.hpp
@@ -19,7 +19,6 @@
#define INCLUDED_UHD_PROPERTY_TREE_HPP
#include <uhd/config.hpp>
-#include <boost/any.hpp>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
@@ -34,14 +33,10 @@ namespace uhd{
*/
template <typename T> class UHD_API property : boost::noncopyable{
public:
- typedef boost::shared_ptr<property> sptr;
typedef boost::function<void(const T &)> subscriber_type;
typedef boost::function<T(void)> publisher_type;
typedef boost::function<T(const T &)> master_type;
- //! Make a new property object
- static sptr make(void);
-
/*!
* Register a master subscriber into the property.
* A master is a special subscriber that coerces the value.
@@ -107,10 +102,10 @@ public:
protected:
//! Internal create property with wild-card type
- virtual void _create(const path_type &path, const boost::any &prop) = 0;
+ virtual void _create(const path_type &path, const boost::shared_ptr<void> &prop) = 0;
//! Internal access property with wild-card type
- virtual boost::any &_access(const path_type &path) = 0;
+ virtual boost::shared_ptr<void> &_access(const path_type &path) = 0;
};
diff --git a/host/include/uhd/property_tree.ipp b/host/include/uhd/property_tree.ipp
index e4520df58..1c61d4937 100644
--- a/host/include/uhd/property_tree.ipp
+++ b/host/include/uhd/property_tree.ipp
@@ -18,15 +18,14 @@
#ifndef INCLUDED_UHD_PROPERTY_TREE_IPP
#define INCLUDED_UHD_PROPERTY_TREE_IPP
-#include <uhd/exception.hpp>
#include <boost/foreach.hpp>
+#include <boost/any.hpp>
#include <vector>
/***********************************************************************
* Implement templated property impl
**********************************************************************/
-namespace uhd{
-namespace /*anon*/{
+namespace uhd{ namespace /*anon*/{
template <typename T> class UHD_API property_impl : public property<T>{
public:
@@ -71,13 +70,7 @@ private:
boost::any _value; //any type so we can assign structs w/ const members
};
-} //namespace /*anon*/
-
-template <typename T> typename property<T>::sptr property<T>::make(void){
- return sptr(new property_impl<T>());
-}
-
-} //namespace uhd
+}} //namespace uhd::/*anon*/
/***********************************************************************
* Implement templated methods for the property tree
@@ -85,17 +78,12 @@ template <typename T> typename property<T>::sptr property<T>::make(void){
namespace uhd{
template <typename T> property<T> &property_tree::create(const path_type &path){
- this->_create(path, property<T>::make());
+ this->_create(path, typename boost::shared_ptr<property<T> >(new property_impl<T>()));
return this->access<T>(path);
}
template <typename T> property<T> &property_tree::access(const path_type &path){
- try{
- return *boost::any_cast<typename property<T>::sptr>(this->_access(path));
- }
- catch(const boost::bad_any_cast &){
- throw uhd::type_error("Cannot cast the property at: " + path.string());
- }
+ return *boost::static_pointer_cast<property<T> >(this->_access(path));
}
} //namespace uhd
diff --git a/host/lib/property_tree.cpp b/host/lib/property_tree.cpp
index 4fbdbad12..4a0b1b061 100644
--- a/host/lib/property_tree.cpp
+++ b/host/lib/property_tree.cpp
@@ -61,7 +61,7 @@ public:
return node->keys();
}
- void _create(const path_type &path, const boost::any &prop){
+ void _create(const path_type &path, const boost::shared_ptr<void> &prop){
boost::mutex::scoped_lock lock(_mutex);
node_type *node = &_root;
@@ -72,7 +72,7 @@ public:
node->prop = prop;
}
- boost::any &_access(const path_type &path){
+ boost::shared_ptr<void> &_access(const path_type &path){
boost::mutex::scoped_lock lock(_mutex);
node_type *node = &_root;
@@ -80,6 +80,7 @@ public:
if (not node->has_key(leaf)) throw_path_not_found(path);
node = &(*node)[leaf];
}
+ if (node->prop.get() == NULL) throw uhd::type_error("Uninitialized property at: " + path.string());
return node->prop;
}
@@ -89,7 +90,7 @@ private:
}
struct node_type : uhd::dict<std::string, node_type>{
- boost::any prop;
+ boost::shared_ptr<void> prop;
} _root;
boost::mutex _mutex;
diff --git a/host/tests/property_test.cpp b/host/tests/property_test.cpp
index 6c80cea70..cd9691dca 100644
--- a/host/tests/property_test.cpp
+++ b/host/tests/property_test.cpp
@@ -18,6 +18,7 @@
#include <boost/test/unit_test.hpp>
#include <uhd/property_tree.hpp>
#include <boost/bind.hpp>
+#include <exception>
#include <iostream>
struct coercer_type{
@@ -34,44 +35,92 @@ struct setter_type{
int _x;
};
+struct getter_type{
+ int doit(void){
+ return _x;
+ }
+
+ int _x;
+};
+
BOOST_AUTO_TEST_CASE(test_prop_simple){
- uhd::property<int>::sptr prop = uhd::property<int>::make();
- prop->set(42);
- BOOST_CHECK_EQUAL(prop->get(), 42);
- prop->set(34);
- BOOST_CHECK_EQUAL(prop->get(), 34);
+ uhd::property_tree::sptr tree = uhd::property_tree::make();
+ uhd::property<int> &prop = tree->create<int>("/");
+ prop.set(42);
+ BOOST_CHECK_EQUAL(prop.get(), 42);
+ prop.set(34);
+ BOOST_CHECK_EQUAL(prop.get(), 34);
}
BOOST_AUTO_TEST_CASE(test_prop_with_subscriber){
- uhd::property<int>::sptr prop = uhd::property<int>::make();
+ uhd::property_tree::sptr tree = uhd::property_tree::make();
+ uhd::property<int> &prop = tree->create<int>("/");
setter_type setter;
- prop->subscribe(boost::bind(&setter_type::doit, &setter, _1));
+ prop.subscribe(boost::bind(&setter_type::doit, &setter, _1));
- prop->set(42);
- BOOST_CHECK_EQUAL(prop->get(), 42);
+ prop.set(42);
+ BOOST_CHECK_EQUAL(prop.get(), 42);
BOOST_CHECK_EQUAL(setter._x, 42);
- prop->set(34);
- BOOST_CHECK_EQUAL(prop->get(), 34);
+ prop.set(34);
+ BOOST_CHECK_EQUAL(prop.get(), 34);
BOOST_CHECK_EQUAL(setter._x, 34);
}
+BOOST_AUTO_TEST_CASE(test_prop_with_publisher){
+ uhd::property_tree::sptr tree = uhd::property_tree::make();
+ uhd::property<int> &prop = tree->create<int>("/");
+
+ getter_type getter;
+ prop.publish(boost::bind(&getter_type::doit, &getter));
+
+ getter._x = 42;
+ prop.set(0); //should not change
+ BOOST_CHECK_EQUAL(prop.get(), 42);
+
+ getter._x = 34;
+ prop.set(0); //should not change
+ BOOST_CHECK_EQUAL(prop.get(), 34);
+}
+
+BOOST_AUTO_TEST_CASE(test_prop_with_publisher_and_subscriber){
+ uhd::property_tree::sptr tree = uhd::property_tree::make();
+ uhd::property<int> &prop = tree->create<int>("/");
+
+ getter_type getter;
+ prop.publish(boost::bind(&getter_type::doit, &getter));
+
+ setter_type setter;
+ prop.subscribe(boost::bind(&setter_type::doit, &setter, _1));
+
+ getter._x = 42;
+ prop.set(0);
+ BOOST_CHECK_EQUAL(prop.get(), 42);
+ BOOST_CHECK_EQUAL(setter._x, 0);
+
+ getter._x = 34;
+ prop.set(1);
+ BOOST_CHECK_EQUAL(prop.get(), 34);
+ BOOST_CHECK_EQUAL(setter._x, 1);
+}
+
BOOST_AUTO_TEST_CASE(test_prop_with_coercion){
- uhd::property<int>::sptr prop = uhd::property<int>::make();
+ uhd::property_tree::sptr tree = uhd::property_tree::make();
+ uhd::property<int> &prop = tree->create<int>("/");
setter_type setter;
- prop->subscribe(boost::bind(&setter_type::doit, &setter, _1));
+ prop.subscribe(boost::bind(&setter_type::doit, &setter, _1));
coercer_type coercer;
- prop->subscribe_master(boost::bind(&coercer_type::doit, &coercer, _1));
+ prop.subscribe_master(boost::bind(&coercer_type::doit, &coercer, _1));
- prop->set(42);
- BOOST_CHECK_EQUAL(prop->get(), 40);
+ prop.set(42);
+ BOOST_CHECK_EQUAL(prop.get(), 40);
BOOST_CHECK_EQUAL(setter._x, 40);
- prop->set(34);
- BOOST_CHECK_EQUAL(prop->get(), 32);
+ prop.set(34);
+ BOOST_CHECK_EQUAL(prop.get(), 32);
BOOST_CHECK_EQUAL(setter._x, 32);
}
@@ -82,6 +131,7 @@ BOOST_AUTO_TEST_CASE(test_prop_tree){
tree->create<int>("/test/prop1");
BOOST_CHECK(tree->exists("/test"));
+ BOOST_CHECK_THROW(tree->access<int>("/test"), std::exception);
BOOST_CHECK(tree->exists("/test/prop0"));
BOOST_CHECK(tree->exists("/test/prop1"));