summaryrefslogtreecommitdiffstats
path: root/include/usrp_uhd/wax.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/usrp_uhd/wax.hpp')
-rw-r--r--include/usrp_uhd/wax.hpp170
1 files changed, 99 insertions, 71 deletions
diff --git a/include/usrp_uhd/wax.hpp b/include/usrp_uhd/wax.hpp
index c8a671a61..f0e7a3acc 100644
--- a/include/usrp_uhd/wax.hpp
+++ b/include/usrp_uhd/wax.hpp
@@ -19,21 +19,18 @@
#define INCLUDED_WAX_HPP
#include <boost/any.hpp>
-#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-#include <boost/pointer_cast.hpp>
#include <iostream>
/*!
* WAX - it's a metaphor!
*
- * The WAX framework allows object to have generic/anytype properties.
- * These properties can be addressed through generic/anytype identifiers.
+ * The WAX framework allows object to have generic/anyobj properties.
+ * These properties can be addressed through generic/anyobj identifiers.
* A property of a WAX object may even be another WAX object.
*
* When a property is a WAX object, the returned value must be an obj pointer.
- * A WAX object provides two types of pointers: obj::ptr and obj::sptr.
+ * A WAX object provides two objs of pointers: obj::ptr and obj::sptr.
* The choice of pointer vs smart pointer depends on the owner of the memory.
*
* Proprties may be referenced though the [] overloaded operator.
@@ -42,101 +39,132 @@
* my_obj[prop1][prop2][prop3] = value
* value = my_obj[prop1][prop2][prop3]
*
- * Any value returned from an access operation is of wax::type.
- * To use this value, it must be cast with wax::cast<new_type>(value).
+ * Any value returned from an access operation is of wax::obj.
+ * To use this value, it must be cast with wax::cast<new_obj>(value).
*/
namespace wax{
- //general typedefs
- typedef boost::any type;
typedef boost::bad_any_cast bad_cast;
- //dummy class declarations
- class obj; class proxy;
-
/*!
* WAX object base class:
- * A wax object subclass should override the set and get methods.
- * The magic of operator chaining is handled by the [] operator.
+ *
+ * A wax obj has two major purposes:
+ * 1) to act as a polymorphic container, just like boost any
+ * 2) to provide a nested set/get properties interface
+ *
+ * Internally, the polymorphic container is handled by a boost any.
+ * For properties, a subclass should override the set and get methods.
+ * For property nesting, wax obj subclasses return special links
+ * to other wax obj subclasses, and the api handles the magic.
*/
class obj{
public:
//obj pointer typedefs
typedef boost::shared_ptr<obj> sptr;
- typedef obj* ptr;
+ typedef obj* ptr;
- //cast derived pointer to obj base class pointer
- template <class T> static sptr cast(boost::shared_ptr<T> r){
- return boost::static_pointer_cast<obj>(r);
- }
- template <class T> static ptr cast(T *r){
- return dynamic_cast<ptr>(r);
- }
-
- //structors
+ /*!
+ * Default constructor:
+ * The contents will be empty.
+ */
obj(void);
- virtual ~obj(void);
- //public interface
- proxy operator[](const type &key);
-
- private:
- //private interface
- virtual void get(const type &key, type &val) = 0;
- virtual void set(const type &key, const type &val) = 0;
- };
+ /*!
+ * Copy constructor:
+ * The contents will be cloned.
+ * \param o another wax::obj
+ */
+ obj(const obj &o);
+
+ /*!
+ * Templated any type constructor:
+ * The contents can be anything.
+ * Uses the boost::any to handle the magic.
+ * \param o an object of any type
+ */
+ template<class T> obj(const T &o){
+ _contents = o;
+ }
- /*!
- * WAX proxy class:
- * Allows the obj [] operator to return a proxy result.
- * This result can be assigned to via the = operator.
- * Or this result can be called again with the [] operator.
- */
- class proxy{
- public:
- //destructors
- ~proxy(void);
+ /*!
+ * Destructor.
+ */
+ virtual ~obj(void);
- //overloaded
- type operator()(void);
- proxy operator[](const type &key);
- proxy operator=(const type &key);
+ /*!
+ * The chaining operator:
+ * This operator allows access objs with properties.
+ * A call to the [] operator will return a new proxy obj.
+ * The proxy object is an obj with special proxy contents.
+ * Assignment and casting can be used on this special object
+ * to access the property referenced by the obj key.
+ * \param key a key to identify a property within this obj
+ * \return a special wax obj that proxies the obj and key
+ */
+ obj operator[](const obj &key);
+
+ /*!
+ * The assignment operator:
+ * This operator allows for assignment of new contents.
+ * In the special case where this obj contains a proxy,
+ * the value will be set to the proxy's property reference.
+ * \param val the new value to assign to the wax obj
+ * \return a reference to this obj (*this)
+ */
+ obj & operator=(const obj &val);
+
+ /*!
+ * Get a link in the chain:
+ * When a wax obj returns another wax obj as part of a get call,
+ * the return value should be set to the result of this method.
+ * Doing so will ensure chain-ability of the returned object.
+ * \return an obj containing a valid link to a wax obj
+ */
+ obj get_link(void) const;
+
+ /*!
+ * Get the type of the contents of this obj.
+ * \return a reference to the type_info
+ */
+ const std::type_info & type(void) const;
private:
- //typedefs for callables from the object that built this proxy
- typedef boost::function<void(const type &)> setter_t;
- typedef boost::function<void(type &)> getter_t;
+ //private interface (override in subclasses)
+ virtual void get(const obj &, obj &);
+ virtual void set(const obj &, const obj &);
+
+ /*!
+ * Resolve the contents of this obj.
+ * In the case where this obj is a proxy,
+ * the referenced property will be resolved.
+ * Otherwise, just get the private contents.
+ * \return a boost any type with contents
+ */
+ boost::any resolve(void) const;
+ template<class T> friend T cast(const obj &);
+
+ //private contents of this obj
+ boost::any _contents;
- //private contructor
- proxy(getter_t, setter_t);
- //access to private contructor
- friend proxy obj::operator[](const type &key);
-
- getter_t d_getter;
- setter_t d_setter;
};
/*!
- * Cast a wax::type into the desired type
- * Usage wax::cast<new_type>(my_value).
+ * Cast a wax::obj into the desired obj.
+ * Usage wax::cast<new_obj>(my_value).
*
- * \param val the any type to cast
- * \return data of the desired type
+ * \param val the obj to cast
+ * \return an object of the desired type
* \throw wax::bad_cast when the cast fails
*/
- template<typename T> T cast(const type & val){
- //special case to handle the proxy
- if (val.type() == typeid(proxy)){
- return cast<T>(boost::any_cast<proxy>(val)());
- }
- //do the type cast
- return boost::any_cast<T>(val);
+ template<class T> T cast(const obj &val){
+ return boost::any_cast<T>(val.resolve());
}
} //namespace wax
-//ability to use types with stream operators
-std::ostream& operator<<(std::ostream &os, const wax::type &x);
+//ability to use wax::obj with stream operators
+std::ostream& operator<<(std::ostream &, const wax::obj &);
#endif /* INCLUDED_WAX_HPP */