aboutsummaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
authorLane Kolbly <lane.kolbly@ni.com>2021-12-23 09:39:39 -0600
committerAaron Rossetto <aaron.rossetto@ni.com>2022-02-07 14:43:46 -0600
commited18ed376bcc71938ad73872148a3146814d831f (patch)
tree86056811e0643d62032a804dc6a76ff4e10028fa /host/include
parenta7c5d70fecb7e7e37c81b0154eb3032d4d1cf6b1 (diff)
downloaduhd-ed18ed376bcc71938ad73872148a3146814d831f.tar.gz
uhd-ed18ed376bcc71938ad73872148a3146814d831f.tar.bz2
uhd-ed18ed376bcc71938ad73872148a3146814d831f.zip
host: Throw exception when accessing properties with incorrect type
Diffstat (limited to 'host/include')
-rw-r--r--host/include/uhd/property_tree.hpp17
-rw-r--r--host/include/uhd/property_tree.ipp19
2 files changed, 26 insertions, 10 deletions
diff --git a/host/include/uhd/property_tree.hpp b/host/include/uhd/property_tree.hpp
index 9fc9b3b97..a1d292858 100644
--- a/host/include/uhd/property_tree.hpp
+++ b/host/include/uhd/property_tree.hpp
@@ -18,6 +18,15 @@
namespace uhd {
/*!
+ * A non-templated class which exists solely so we can
+ * dynamic_cast between properties.
+ */
+class UHD_API property_iface {
+public:
+ virtual ~property_iface() = default;
+};
+
+/*!
* A templated property interface for holding the state
* associated with a property in a uhd::property_tree
* and registering callbacks when that value changes.
@@ -65,7 +74,7 @@ namespace uhd {
* - T must have an assignment operator
*/
template <typename T>
-class UHD_API_HEADER property : uhd::noncopyable
+class UHD_API_HEADER property : uhd::noncopyable, public property_iface
{
public:
typedef std::function<void(const T&)> subscriber_type;
@@ -245,14 +254,14 @@ public:
private:
//! Internal pop function
- virtual std::shared_ptr<void> _pop(const fs_path& path) = 0;
+ virtual std::shared_ptr<property_iface> _pop(const fs_path& path) = 0;
//! Internal create property with wild-card type
virtual void _create(const fs_path& path,
- const std::shared_ptr<void>& prop) = 0;
+ const std::shared_ptr<property_iface>& prop) = 0;
//! Internal access property with wild-card type
- virtual std::shared_ptr<void>& _access(const fs_path& path) const = 0;
+ virtual std::shared_ptr<property_iface>& _access(const fs_path& path) const = 0;
};
} // namespace uhd
diff --git a/host/include/uhd/property_tree.ipp b/host/include/uhd/property_tree.ipp
index 273227174..e9dd3072e 100644
--- a/host/include/uhd/property_tree.ipp
+++ b/host/include/uhd/property_tree.ipp
@@ -9,8 +9,8 @@
#pragma once
#include <uhd/exception.hpp>
-#include <vector>
#include <memory>
+#include <vector>
/***********************************************************************
* Implement templated property impl
@@ -179,21 +179,28 @@ namespace uhd {
template <typename T>
property<T>& property_tree::create(const fs_path& path, coerce_mode_t coerce_mode)
{
- this->_create(path, std::make_shared<property_impl<T> >(coerce_mode));
+ this->_create(path, std::make_shared<property_impl<T>>(coerce_mode));
return this->access<T>(path);
}
template <typename T>
property<T>& property_tree::access(const fs_path& path)
{
- return *std::static_pointer_cast<property<T> >(
- this->_access(path));
+ auto ptr = std::dynamic_pointer_cast<property<T>>(this->_access(path));
+ if (!ptr) {
+ throw uhd::type_error("Property " + path + " exists, but was accessed with wrong type");
+ }
+ return *ptr;
}
template <typename T>
-typename std::shared_ptr<property<T> > property_tree::pop(const fs_path& path)
+typename std::shared_ptr<property<T>> property_tree::pop(const fs_path& path)
{
- return std::static_pointer_cast<property<T> >(this->_pop(path));
+ auto ptr = std::dynamic_pointer_cast<property<T>>(this->_pop(path));
+ if (!ptr) {
+ throw uhd::type_error("Property " + path + " exists, but was accessed with wrong type");
+ }
+ return ptr;
}
} // namespace uhd