summaryrefslogtreecommitdiff
path: root/src/stable/variant.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/variant.h')
-rw-r--r--src/stable/variant.h418
1 files changed, 209 insertions, 209 deletions
diff --git a/src/stable/variant.h b/src/stable/variant.h
index 6837954..227e246 100644
--- a/src/stable/variant.h
+++ b/src/stable/variant.h
@@ -20,217 +20,217 @@
20 20
21namespace Bu 21namespace Bu
22{ 22{
23 class String; 23 class String;
24 class Formatter; 24 class Formatter;
25 class Variant; 25 class Variant;
26 /** @cond DEVEL */ 26 /** @cond DEVEL */
27 template<class t> class VariantType; 27 template<class t> class VariantType;
28 28
29 class VariantTypeRoot 29 class VariantTypeRoot
30 { 30 {
31 public: 31 public:
32 VariantTypeRoot(); 32 VariantTypeRoot();
33 virtual ~VariantTypeRoot(); 33 virtual ~VariantTypeRoot();
34 34
35 virtual const std::type_info &getType() const=0; 35 virtual const std::type_info &getType() const=0;
36 virtual VariantTypeRoot *clone() const=0; 36 virtual VariantTypeRoot *clone() const=0;
37 virtual void format( Bu::Formatter &f ) const=0; 37 virtual void format( Bu::Formatter &f ) const=0;
38 }; 38 };
39 39
40 template<class t> 40 template<class t>
41 class VariantType : public VariantTypeRoot 41 class VariantType : public VariantTypeRoot
42 { 42 {
43 friend class Variant; 43 friend class Variant;
44 private: 44 private:
45 VariantType() 45 VariantType()
46 { 46 {
47 } 47 }
48 48
49 VariantType( const t &d ) : 49 VariantType( const t &d ) :
50 data( d ) 50 data( d )
51 { 51 {
52 } 52 }
53 53
54 VariantType( const VariantType<t> &vt ) : 54 VariantType( const VariantType<t> &vt ) :
55 data( vt.data ) 55 data( vt.data )
56 { 56 {
57 } 57 }
58 58
59 virtual ~VariantType() 59 virtual ~VariantType()
60 { 60 {
61 } 61 }
62 62
63 public: 63 public:
64 t &getData() 64 t &getData()
65 { 65 {
66 return data; 66 return data;
67 } 67 }
68 68
69 const t &getData() const 69 const t &getData() const
70 { 70 {
71 return data; 71 return data;
72 } 72 }
73 73
74 virtual void format( Formatter &f ) const 74 virtual void format( Formatter &f ) const
75 { 75 {
76 f << data; 76 f << data;
77 } 77 }
78 78
79 virtual const std::type_info &getType() const 79 virtual const std::type_info &getType() const
80 { 80 {
81 return typeid( data ); 81 return typeid( data );
82 } 82 }
83 83
84 VariantType<t> operator=( const t &rhs ) 84 VariantType<t> operator=( const t &rhs )
85 { 85 {
86 data = rhs; 86 data = rhs;
87 87
88 return *this; 88 return *this;
89 } 89 }
90 90
91 virtual VariantTypeRoot *clone() const 91 virtual VariantTypeRoot *clone() const
92 { 92 {
93 return new VariantType<t>( *this ); 93 return new VariantType<t>( *this );
94 } 94 }
95 95
96 private: 96 private:
97 t data; 97 t data;
98 }; 98 };
99 /** @endcond */ 99 /** @endcond */
100 100
101 /** 101 /**
102 * Store any data type and access it safely. Variant gives you a way to 102 * Store any data type and access it safely. Variant gives you a way to
103 * pass arbitrary data types around without having to worry about what 103 * pass arbitrary data types around without having to worry about what
104 * type a variable is. It allows code to be easily extended and to manage 104 * type a variable is. It allows code to be easily extended and to manage
105 * data without having to know what type it is ahead of time. 105 * data without having to know what type it is ahead of time.
106 * 106 *
107 * Because of the generic method that this class was implemented it may seem 107 * Because of the generic method that this class was implemented it may seem
108 * to have some drawbacks compared to other Variant classes you may have 108 * to have some drawbacks compared to other Variant classes you may have
109 * seen, however it is fairly easy to get it to do just about anything you 109 * seen, however it is fairly easy to get it to do just about anything you
110 * may need. It is also very low overhead. On most compilers the class 110 * may need. It is also very low overhead. On most compilers the class
111 * itself has only 3 words of overhead + the size of the variable you store 111 * itself has only 3 words of overhead + the size of the variable you store
112 * in it. And, since many parts of it are templatized they can often be 112 * in it. And, since many parts of it are templatized they can often be
113 * optimized quite a bit. 113 * optimized quite a bit.
114 */ 114 */
115 class Variant 115 class Variant
116 { 116 {
117 friend Bu::Formatter &operator<<( Bu::Formatter &f, const Variant &v ); 117 friend Bu::Formatter &operator<<( Bu::Formatter &f, const Variant &v );
118 public: 118 public:
119 Variant(); 119 Variant();
120 Variant( const Variant &v ); 120 Variant( const Variant &v );
121 Variant( const char *t ); 121 Variant( const char *t );
122 template<class t> 122 template<class t>
123 Variant( const t &v ) : 123 Variant( const t &v ) :
124 pCore( new VariantType<t>() ) 124 pCore( new VariantType<t>() )
125 { 125 {
126 (*dynamic_cast<VariantType<t> *>(pCore)) = v; 126 (*dynamic_cast<VariantType<t> *>(pCore)) = v;
127 } 127 }
128 virtual ~Variant(); 128 virtual ~Variant();
129 129
130 Bu::String toString() const; 130 Bu::String toString() const;
131 bool isSet() const; 131 bool isSet() const;
132 const std::type_info &getType() const; 132 const std::type_info &getType() const;
133 133
134 Variant &operator=( const Variant &rhs ); 134 Variant &operator=( const Variant &rhs );
135 135
136 template<class t> 136 template<class t>
137 Variant &operator=( const t &rhs ) 137 Variant &operator=( const t &rhs )
138 { 138 {
139 if( pCore ) // && pCore->getType() != typeid(t) ) 139 if( pCore ) // && pCore->getType() != typeid(t) )
140 { 140 {
141 delete pCore; 141 delete pCore;
142 pCore = NULL; 142 pCore = NULL;
143 } 143 }
144 pCore = new VariantType<t>(); 144 pCore = new VariantType<t>();
145 (*dynamic_cast<VariantType<t> *>(pCore)) = rhs; 145 (*dynamic_cast<VariantType<t> *>(pCore)) = rhs;
146 return *this; 146 return *this;
147 } 147 }
148 148
149 template<class t> 149 template<class t>
150 t &get() 150 t &get()
151 { 151 {
152 if( !pCore ) 152 if( !pCore )
153 { 153 {
154 throw Bu::ExceptionBase("No data!"); 154 throw Bu::ExceptionBase("No data!");
155 } 155 }
156 if( pCore->getType() != typeid(t) ) 156 if( pCore->getType() != typeid(t) )
157 { 157 {
158 throw Bu::ExceptionBase("Invalid type conversion."); 158 throw Bu::ExceptionBase("Invalid type conversion.");
159 } 159 }
160 return dynamic_cast<VariantType<t> *>(pCore)->getData(); 160 return dynamic_cast<VariantType<t> *>(pCore)->getData();
161 } 161 }
162 162
163 template<class t> 163 template<class t>
164 t &get() const 164 t &get() const
165 { 165 {
166 if( !pCore ) 166 if( !pCore )
167 { 167 {
168 throw Bu::ExceptionBase("No data!"); 168 throw Bu::ExceptionBase("No data!");
169 } 169 }
170 if( pCore->getType() != typeid(t) ) 170 if( pCore->getType() != typeid(t) )
171 { 171 {
172 throw Bu::ExceptionBase("Invalid type conversion."); 172 throw Bu::ExceptionBase("Invalid type conversion.");
173 } 173 }
174 return dynamic_cast<VariantType<t> *>(pCore)->getData(); 174 return dynamic_cast<VariantType<t> *>(pCore)->getData();
175 } 175 }
176 176
177 template<class t> 177 template<class t>
178 void set( const t &val ) 178 void set( const t &val )
179 { 179 {
180 if( pCore && pCore->getType() != typeid(t) ) 180 if( pCore && pCore->getType() != typeid(t) )
181 { 181 {
182 delete pCore; 182 delete pCore;
183 pCore = NULL; 183 pCore = NULL;
184 } 184 }
185 pCore = new VariantType<t>(); 185 pCore = new VariantType<t>();
186 (*dynamic_cast<VariantType<t> *>(pCore)) = val; 186 (*dynamic_cast<VariantType<t> *>(pCore)) = val;
187 } 187 }
188 188
189 template<class t> 189 template<class t>
190 bool isType() const 190 bool isType() const
191 { 191 {
192 return pCore->getType() == typeid(t); 192 return pCore->getType() == typeid(t);
193 } 193 }
194 194
195 template<class t> 195 template<class t>
196 operator t() 196 operator t()
197 { 197 {
198 if( !pCore ) 198 if( !pCore )
199 { 199 {
200 throw Bu::ExceptionBase("No data!"); 200 throw Bu::ExceptionBase("No data!");
201 } 201 }
202 if( pCore->getType() != typeid(t) ) 202 if( pCore->getType() != typeid(t) )
203 { 203 {
204 throw Bu::ExceptionBase("Invalid type conversion."); 204 throw Bu::ExceptionBase("Invalid type conversion.");
205 } 205 }
206 return dynamic_cast<VariantType<t> *>(pCore)->getData(); 206 return dynamic_cast<VariantType<t> *>(pCore)->getData();
207 } 207 }
208 208
209 template<class t> 209 template<class t>
210 operator t() const 210 operator t() const
211 { 211 {
212 if( !pCore ) 212 if( !pCore )
213 { 213 {
214 throw Bu::ExceptionBase("No data!"); 214 throw Bu::ExceptionBase("No data!");
215 } 215 }
216 if( pCore->getType() != typeid(t) ) 216 if( pCore->getType() != typeid(t) )
217 { 217 {
218 throw Bu::ExceptionBase("Invalid type conversion."); 218 throw Bu::ExceptionBase("Invalid type conversion.");
219 } 219 }
220 return dynamic_cast<VariantType<t> *>(pCore)->getData(); 220 return dynamic_cast<VariantType<t> *>(pCore)->getData();
221 } 221 }
222 222
223 private: 223 private:
224 VariantTypeRoot *pCore; 224 VariantTypeRoot *pCore;
225 }; 225 };
226/* 226/*
227 template<class t> 227 template<class t>
228 Bu::Formatter &operator<<( Bu::Formatter &f, const VariantType<t> &vt ) 228 Bu::Formatter &operator<<( Bu::Formatter &f, const VariantType<t> &vt )
229 { 229 {
230 return f << vt.getData; 230 return f << vt.getData;
231 }*/ 231 }*/
232 232
233 Bu::Formatter &operator<<( Bu::Formatter &f, const Variant &v ); 233 Bu::Formatter &operator<<( Bu::Formatter &f, const Variant &v );
234}; 234};
235 235
236#endif 236#endif