From cc8caeb1230fbaed4a6bc64848a584d51b69362a Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Mon, 1 Feb 2010 12:35:34 -0800
Subject: Work on the properties framwork with wax::obj. Now the obj handles
 all 3 things in 1, properties, polymorphic container, proxy.

---
 include/usrp_uhd/device.hpp            |   2 +-
 include/usrp_uhd/gain_handler.hpp      |  20 ++--
 include/usrp_uhd/props.hpp             |   4 +-
 include/usrp_uhd/usrp/dboard/base.hpp  |  16 ++--
 include/usrp_uhd/usrp/mboard/base.hpp  |   4 +-
 include/usrp_uhd/usrp/mboard/test.hpp  |   4 +-
 include/usrp_uhd/usrp/mboard/usrp2.hpp |   4 +-
 include/usrp_uhd/usrp/usrp.hpp         |   4 +-
 include/usrp_uhd/utils.hpp             |   4 +-
 include/usrp_uhd/wax.hpp               | 170 +++++++++++++++++++--------------
 10 files changed, 130 insertions(+), 102 deletions(-)

(limited to 'include/usrp_uhd')

diff --git a/include/usrp_uhd/device.hpp b/include/usrp_uhd/device.hpp
index b2627f887..e0356feb0 100644
--- a/include/usrp_uhd/device.hpp
+++ b/include/usrp_uhd/device.hpp
@@ -82,7 +82,7 @@ public:
     virtual void recv_raw(const recv_args_t &) = 0;
 
     //connect dsps and subdevs
-    void connect(const wax::type &src, const wax::type &sink);
+    void connect(const wax::obj &src, const wax::obj &sink);
 };
 
 } //namespace usrp_uhd
diff --git a/include/usrp_uhd/gain_handler.hpp b/include/usrp_uhd/gain_handler.hpp
index e036ab701..22e987803 100644
--- a/include/usrp_uhd/gain_handler.hpp
+++ b/include/usrp_uhd/gain_handler.hpp
@@ -51,7 +51,7 @@ public:
      * Ensures that the gain name is valid.
      * \return true for handled, false to pass on
      */
-    bool intercept_get(const wax::type &key, wax::type &val);
+    bool intercept_get(const wax::obj &key, wax::obj &val);
 
     /*!
      * Intercept sets for overall gain.
@@ -59,16 +59,16 @@ public:
      * Ensures that the new gain is within range.
      * \return true for handled, false to pass on
      */
-    bool intercept_set(const wax::type &key, const wax::type &val);
+    bool intercept_set(const wax::obj &key, const wax::obj &val);
 
 private:
 
     wax::obj::ptr  _wax_obj_ptr;
-    wax::type      _gain_prop;
-    wax::type      _gain_min_prop;
-    wax::type      _gain_max_prop;
-    wax::type      _gain_step_prop;
-    wax::type      _gain_names_prop;
+    wax::obj      _gain_prop;
+    wax::obj      _gain_min_prop;
+    wax::obj      _gain_max_prop;
+    wax::obj      _gain_step_prop;
+    wax::obj      _gain_names_prop;
 
     /*!
      * Verify that the key is valid:
@@ -76,14 +76,14 @@ private:
      * If the name if not valid, throw a std::invalid_argument.
      * The name can only be valid if its in the list of gain names.
      */
-    void _check_key(const wax::type &key);
+    void _check_key(const wax::obj &key);
 
     /*
      * Private interface to test if two wax types are equal:
      * The constructor will bind an instance of this for a specific type.
      * This bound equals functions allows the intercept methods to be non-templated.
      */
-    template <class T> static bool is_equal(const wax::type &a, const wax::type &b){
+    template <class T> static bool is_equal(const wax::obj &a, const wax::obj &b){
         try{
             return wax::cast<T>(a) == wax::cast<T>(b);
         }
@@ -91,7 +91,7 @@ private:
             return false;
         }
     }
-    boost::function<bool(const wax::type &, const wax::type &)> _is_equal;
+    boost::function<bool(const wax::obj &, const wax::obj &)> _is_equal;
 
 };
 
diff --git a/include/usrp_uhd/props.hpp b/include/usrp_uhd/props.hpp
index 6370bdd28..de3280969 100644
--- a/include/usrp_uhd/props.hpp
+++ b/include/usrp_uhd/props.hpp
@@ -42,14 +42,14 @@ namespace usrp_uhd{
 
     //typedef for handling named properties
     typedef std::vector<std::string> prop_names_t;
-    typedef boost::tuple<wax::type, std::string> named_prop_t;
+    typedef boost::tuple<wax::obj, std::string> named_prop_t;
 
     /*!
      * Utility function to separate a named property into its components.
      * \param key a reference to the prop object
      * \param name a reference to the name object
      */
-    inline named_prop_t extract_named_prop(const wax::type &key, const std::string &name = ""){
+    inline named_prop_t extract_named_prop(const wax::obj &key, const std::string &name = ""){
         if (key.type() == typeid(named_prop_t)){
             return wax::cast<named_prop_t>(key);
         }
diff --git a/include/usrp_uhd/usrp/dboard/base.hpp b/include/usrp_uhd/usrp/dboard/base.hpp
index 161d47a9e..50896b9a8 100644
--- a/include/usrp_uhd/usrp/dboard/base.hpp
+++ b/include/usrp_uhd/usrp/dboard/base.hpp
@@ -43,10 +43,10 @@ public:
     virtual ~base(void);
 
     //interface
-    virtual void rx_get(const wax::type &key, wax::type &val) = 0;
-    virtual void rx_set(const wax::type &key, const wax::type &val) = 0;
-    virtual void tx_get(const wax::type &key, wax::type &val) = 0;
-    virtual void tx_set(const wax::type &key, const wax::type &val) = 0;
+    virtual void rx_get(const wax::obj &key, wax::obj &val) = 0;
+    virtual void rx_set(const wax::obj &key, const wax::obj &val) = 0;
+    virtual void tx_get(const wax::obj &key, wax::obj &val) = 0;
+    virtual void tx_set(const wax::obj &key, const wax::obj &val) = 0;
 
 protected:
     std::string get_subdev_name(void);
@@ -84,8 +84,8 @@ public:
     virtual ~rx_base(void);
 
     //override here so the derived classes cannot
-    void tx_get(const wax::type &key, wax::type &val);
-    void tx_set(const wax::type &key, const wax::type &val);
+    void tx_get(const wax::obj &key, wax::obj &val);
+    void tx_set(const wax::obj &key, const wax::obj &val);
 };
 
 /*!
@@ -102,8 +102,8 @@ public:
     virtual ~tx_base(void);
 
     //override here so the derived classes cannot
-    void rx_get(const wax::type &key, wax::type &val);
-    void rx_set(const wax::type &key, const wax::type &val);
+    void rx_get(const wax::obj &key, wax::obj &val);
+    void rx_set(const wax::obj &key, const wax::obj &val);
 };
 
 }}} //namespace
diff --git a/include/usrp_uhd/usrp/mboard/base.hpp b/include/usrp_uhd/usrp/mboard/base.hpp
index 59236dce9..65810f329 100644
--- a/include/usrp_uhd/usrp/mboard/base.hpp
+++ b/include/usrp_uhd/usrp/mboard/base.hpp
@@ -36,8 +36,8 @@ public:
     //TODO other api calls
 
 private:
-    virtual void get(const wax::type &, wax::type &) = 0;
-    virtual void set(const wax::type &, const wax::type &) = 0;
+    virtual void get(const wax::obj &, wax::obj &) = 0;
+    virtual void set(const wax::obj &, const wax::obj &) = 0;
 };
 
 }}} //namespace
diff --git a/include/usrp_uhd/usrp/mboard/test.hpp b/include/usrp_uhd/usrp/mboard/test.hpp
index 75e1f838f..fc1ea6e70 100644
--- a/include/usrp_uhd/usrp/mboard/test.hpp
+++ b/include/usrp_uhd/usrp/mboard/test.hpp
@@ -35,8 +35,8 @@ public:
     ~test(void);
 
 private:
-    void get(const wax::type &, wax::type &);
-    void set(const wax::type &, const wax::type &);
+    void get(const wax::obj &, wax::obj &);
+    void set(const wax::obj &, const wax::obj &);
 
     std::map<std::string, dboard::manager::sptr> _dboard_managers;
 };
diff --git a/include/usrp_uhd/usrp/mboard/usrp2.hpp b/include/usrp_uhd/usrp/mboard/usrp2.hpp
index ea0083bc4..a8e950d93 100644
--- a/include/usrp_uhd/usrp/mboard/usrp2.hpp
+++ b/include/usrp_uhd/usrp/mboard/usrp2.hpp
@@ -42,8 +42,8 @@ public:
     ~usrp2(void);
 
 private:
-    void get(const wax::type &, wax::type &);
-    void set(const wax::type &, const wax::type &);
+    void get(const wax::obj &, wax::obj &);
+    void set(const wax::obj &, const wax::obj &);
 
     std::map<std::string, dboard::manager::sptr> _dboard_managers;
 };
diff --git a/include/usrp_uhd/usrp/usrp.hpp b/include/usrp_uhd/usrp/usrp.hpp
index a8cd1dc7c..a8a052b52 100644
--- a/include/usrp_uhd/usrp/usrp.hpp
+++ b/include/usrp_uhd/usrp/usrp.hpp
@@ -39,8 +39,8 @@ public:
     void recv_raw(const recv_args_t &);
 
 private:
-    void get(const wax::type &, wax::type &);
-    void set(const wax::type &, const wax::type &);
+    void get(const wax::obj &, wax::obj &);
+    void set(const wax::obj &, const wax::obj &);
 
     std::map<std::string, mboard::base::sptr> _mboards;
     boost::function<void(const device::send_args_t &)> _send_raw_cb;
diff --git a/include/usrp_uhd/utils.hpp b/include/usrp_uhd/utils.hpp
index 6a2848b96..a8f1c132d 100644
--- a/include/usrp_uhd/utils.hpp
+++ b/include/usrp_uhd/utils.hpp
@@ -48,11 +48,11 @@ template<typename T> T signum(T n){
 inline void tune(
     freq_t target_freq,
     freq_t lo_offset,
-    wax::proxy subdev_freq_proxy,
+    wax::obj subdev_freq_proxy,
     bool subdev_quadrature,
     bool subdev_spectrum_inverted,
     bool subdev_is_tx,
-    wax::proxy dsp_freq_proxy,
+    wax::obj dsp_freq_proxy,
     freq_t dsp_sample_rate
 ){
     // Ask the d'board to tune as closely as it can to target_freq+lo_offset
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 */
-- 
cgit v1.2.3