Statistics
| Branch: | Tag: | Revision:

root / host / include / uhd / wax.hpp @ eb7e709b

History | View | Annotate | Download (5.42 KB)

1
//
2
// Copyright 2010 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

    
18
#ifndef INCLUDED_WAX_HPP
19
#define INCLUDED_WAX_HPP
20

    
21
#include <boost/any.hpp>
22
#include <iostream>
23

    
24
/*!
25
 * WAX - it's a metaphor!
26
 *
27
 * The WAX framework allows object to have generic/anyobj properties.
28
 * These properties can be addressed through generic/anyobj identifiers.
29
 * A property of a WAX object may even be another WAX object.
30
 *
31
 * When a property is a WAX object, the returned value must be an obj pointer.
32
 * A WAX object provides two objs of pointers: obj::ptr and obj::sptr.
33
 * The choice of pointer vs smart pointer depends on the owner of the memory.
34
 *
35
 * Proprties may be referenced though the [] overloaded operator.
36
 * The [] operator returns a special proxy that allows for assigment.
37
 * Also, the [] operators may be chained as in the folowing examples:
38
 *   my_obj[prop1][prop2][prop3] = value
39
 *   value = my_obj[prop1][prop2][prop3]
40
 *
41
 * Any value returned from an access operation is of wax::obj.
42
 * To use this value, it must be cast with wax::cast<new_obj>(value).
43
 */
44

    
45
namespace wax{
46

    
47
    /*!
48
     * WAX object base class:
49
     *
50
     * A wax obj has two major purposes:
51
     *   1) to act as a polymorphic container, just like boost any
52
     *   2) to provide a nested set/get properties interface
53
     *
54
     * Internally, the polymorphic container is handled by a boost any.
55
     * For properties, a subclass should override the set and get methods.
56
     * For property nesting, wax obj subclasses return special links
57
     * to other wax obj subclasses, and the api handles the magic.
58
     */
59
    class obj{
60
    public:
61

    
62
        /*!
63
         * Default constructor:
64
         * The contents will be empty.
65
         */
66
        obj(void);
67

    
68
        /*!
69
         * Copy constructor:
70
         * The contents will be cloned.
71
         * \param o another wax::obj
72
         */
73
        obj(const obj &o);
74

    
75
        /*!
76
         * Templated any type constructor:
77
         * The contents can be anything.
78
         * Uses the boost::any to handle the magic.
79
         * \param o an object of any type
80
         */
81
        template<class T> obj(const T &o){
82
            _contents = o;
83
        }
84

    
85
        /*!
86
         * Destructor.
87
         */
88
        virtual ~obj(void);
89

    
90
        /*!
91
         * The chaining operator:
92
         * This operator allows access objs with properties.
93
         * A call to the [] operator will return a new proxy obj.
94
         * The proxy object is an obj with special proxy contents.
95
         * Assignment and casting can be used on this special object
96
         * to access the property referenced by the obj key.
97
         * \param key a key to identify a property within this obj
98
         * \return a special wax obj that proxies the obj and key
99
         */
100
        obj operator[](const obj &key);
101

    
102
        /*!
103
         * The assignment operator:
104
         * This operator allows for assignment of new contents.
105
         * In the special case where this obj contains a proxy,
106
         * the value will be set to the proxy's property reference.
107
         * \param val the new value to assign to the wax obj
108
         * \return a reference to this obj (*this)
109
         */
110
        obj & operator=(const obj &val);
111

    
112
        /*!
113
         * Get a link in the chain:
114
         * When a wax obj returns another wax obj as part of a get call,
115
         * the return value should be set to the result of this method.
116
         * Doing so will ensure chain-ability of the returned object.
117
         * \return an obj containing a valid link to a wax obj
118
         */
119
        obj get_link(void) const;
120

    
121
        /*!
122
         * Get the type of the contents of this obj.
123
         * \return a reference to the type_info
124
         */
125
        const std::type_info & type(void) const;
126

    
127
    private:
128
        //private interface (override in subclasses)
129
        virtual void get(const obj &, obj &);
130
        virtual void set(const obj &, const obj &);
131

    
132
        /*!
133
         * Resolve the contents of this obj.
134
         * In the case where this obj is a proxy,
135
         * the referenced property will be resolved.
136
         * Otherwise, just get the private contents.
137
         * \return a boost any type with contents
138
         */
139
        boost::any resolve(void) const;
140
        template<class T> friend T cast(const obj &);
141

    
142
        //private contents of this obj
143
        boost::any _contents;
144

    
145
    };
146

    
147
    /*!
148
     * The wax::bad cast will be thrown when
149
     * cast is called with the wrong typeid.
150
     */
151
    typedef boost::bad_any_cast bad_cast;
152

    
153
    /*!
154
     * Cast a wax::obj into the desired obj.
155
     * Usage wax::cast<new_obj>(my_value).
156
     *
157
     * \param val the obj to cast
158
     * \return an object of the desired type
159
     * \throw wax::bad_cast when the cast fails
160
     */
161
    template<class T> T cast(const obj &val){
162
        return boost::any_cast<T>(val.resolve());
163
    }
164

    
165
} //namespace wax
166

    
167
#endif /* INCLUDED_WAX_HPP */