diff options
Diffstat (limited to '')
-rw-r--r-- | src/stable/variant.h | 418 |
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 | ||
21 | namespace Bu | 21 | namespace 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 |