diff options
author | Josh Blum <josh@joshknows.com> | 2011-06-28 21:26:28 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-06-28 21:26:28 -0700 |
commit | d2f79c07281604c1b48ec81f1cdb2754e97bbe65 (patch) | |
tree | e41a2000af165384bbe03b1ff6d6ea118bbbcf1f | |
parent | ebd2ecc6ff2b82cb06701bbcda17d4caaa4ba8c1 (diff) | |
download | uhd-d2f79c07281604c1b48ec81f1cdb2754e97bbe65.tar.gz uhd-d2f79c07281604c1b48ec81f1cdb2754e97bbe65.tar.bz2 uhd-d2f79c07281604c1b48ec81f1cdb2754e97bbe65.zip |
uhd: added properties unit tests, use shared ptr<void> in tree
-rw-r--r-- | host/include/uhd/property_tree.hpp | 9 | ||||
-rw-r--r-- | host/include/uhd/property_tree.ipp | 22 | ||||
-rw-r--r-- | host/lib/property_tree.cpp | 7 | ||||
-rw-r--r-- | host/tests/property_test.cpp | 86 |
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")); |