Added wxDECLARE_ANY_TYPE(CLS, DECL) and documented for what kind of situation it...
[wxWidgets.git] / src / common / any.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/any.cpp
3 // Purpose: wxAny class, container for any type
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: 07/05/2009
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #include "wx/any.h"
20
21 #if wxUSE_ANY
22
23 #ifndef WX_PRECOMP
24 #include "wx/math.h"
25 #include "wx/crt.h"
26 #endif
27
28 #include "wx/vector.h"
29 #include "wx/module.h"
30
31 using namespace wxPrivate;
32
33 //-------------------------------------------------------------------------
34 // wxAnyValueTypeGlobals
35 //-------------------------------------------------------------------------
36
37 //
38 // Helper class to manage wxAnyValueType instances and other
39 // related global variables.
40 //
41 // NB: We really need to have wxAnyValueType instances allocated
42 // in heap. They are stored as static template member variables,
43 // and with them we just can't be too careful (eg. not allocating
44 // them in heap broke the type identification in GCC).
45 //
46 class wxAnyValueTypeGlobals
47 {
48 public:
49 wxAnyValueTypeGlobals()
50 {
51 }
52 ~wxAnyValueTypeGlobals()
53 {
54 for ( size_t i=0; i<m_valueTypes.size(); i++ )
55 delete m_valueTypes[i];
56 }
57
58 void RegisterValueType(wxAnyValueType* valueType)
59 {
60 m_valueTypes.push_back(valueType);
61 }
62
63 private:
64 wxVector<wxAnyValueType*> m_valueTypes;
65 };
66
67 static wxAnyValueTypeGlobals* g_wxAnyValueTypeGlobals = NULL;
68
69 //
70 // This class is to make sure that wxAnyValueType instances
71 // etc. get freed correctly. We must use a separate wxAnyValueTypeGlobals
72 // because wxModule itself is instantiated too late.
73 //
74 class wxAnyValueTypeGlobalsManager : public wxModule
75 {
76 DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager)
77 public:
78 wxAnyValueTypeGlobalsManager() : wxModule() { }
79 virtual ~wxAnyValueTypeGlobalsManager() { }
80
81 virtual bool OnInit()
82 {
83 return true;
84 }
85 virtual void OnExit()
86 {
87 delete g_wxAnyValueTypeGlobals;
88 g_wxAnyValueTypeGlobals = NULL;
89 }
90 private:
91 };
92
93 IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)
94
95
96 //-------------------------------------------------------------------------
97 // wxAnyValueType
98 //-------------------------------------------------------------------------
99
100 wxAnyValueType::wxAnyValueType()
101 {
102 if ( !g_wxAnyValueTypeGlobals )
103 g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();
104
105 g_wxAnyValueTypeGlobals->RegisterValueType(this);
106 }
107
108 //-------------------------------------------------------------------------
109 // Dynamic conversion member functions
110 //-------------------------------------------------------------------------
111
112 //
113 // Define integer minimum and maximum as helpers
114 #ifdef wxLongLong_t
115 const wxAnyBaseIntType UseIntMin = wxINT64_MIN;
116 const wxAnyBaseUintType UseIntMax = wxINT64_MAX;
117 const wxAnyBaseUintType UseUintMax = wxUINT64_MAX;
118 #else
119 const wxAnyBaseIntType UseIntMin = LONG_MIN;
120 const wxAnyBaseUintType UseUintMax = ULONG_MAX;
121 const wxAnyBaseUintType UseIntMax = LONG_MAX;
122 #endif
123
124 const double UseIntMinF = static_cast<double>(UseIntMin);
125 #ifndef __VISUALC6__
126 const double UseIntMaxF = static_cast<double>(UseIntMax);
127 const double UseUintMaxF = static_cast<double>(UseUintMax);
128 #else
129 // VC6 doesn't implement conversion from unsigned __int64 to double
130 const wxAnyBaseIntType UseIntMax0 = static_cast<wxAnyBaseIntType>(UseIntMax);
131 const wxAnyBaseIntType UseUintMax0 = static_cast<wxAnyBaseIntType>(UseUintMax);
132 const double UseIntMaxF = static_cast<double>(UseIntMax0);
133 const double UseUintMaxF = static_cast<double>(UseUintMax0);
134 #endif
135
136
137 bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src,
138 wxAnyValueType* dstType,
139 wxAnyValueBuffer& dst) const
140 {
141 wxAnyBaseIntType value = GetValue(src);
142 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
143 {
144 #ifdef wxLongLong_t
145 wxLongLong ll(value);
146 wxString s = ll.ToString();
147 #else
148 wxString s = wxString::Format(wxS("%ld"), (long)value);
149 #endif
150 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
151 }
152 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
153 {
154 if ( value < 0 )
155 return false;
156 wxAnyBaseUintType ul = (wxAnyBaseUintType) value;
157 wxAnyValueTypeImplUint::SetValue(ul, dst);
158 }
159 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
160 {
161 double value2 = static_cast<double>(value);
162 wxAnyValueTypeImplDouble::SetValue(value2, dst);
163 }
164 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
165 {
166 bool value2 = value ? true : false;
167 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
168 }
169 else
170 return false;
171
172 return true;
173 }
174
175 bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src,
176 wxAnyValueType* dstType,
177 wxAnyValueBuffer& dst) const
178 {
179 wxAnyBaseUintType value = GetValue(src);
180 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
181 {
182 #ifdef wxLongLong_t
183 wxULongLong ull(value);
184 wxString s = ull.ToString();
185 #else
186 wxString s = wxString::Format(wxS("%lu"), (long)value);
187 #endif
188 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
189 }
190 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
191 {
192 if ( value > UseIntMax )
193 return false;
194 wxAnyBaseIntType l = (wxAnyBaseIntType) value;
195 wxAnyValueTypeImplInt::SetValue(l, dst);
196 }
197 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
198 {
199 #ifndef __VISUALC6__
200 double value2 = static_cast<double>(value);
201 #else
202 // VC6 doesn't implement conversion from unsigned __int64 to double
203 wxAnyBaseIntType value0 = static_cast<wxAnyBaseIntType>(value);
204 double value2 = static_cast<double>(value0);
205 #endif
206 wxAnyValueTypeImplDouble::SetValue(value2, dst);
207 }
208 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
209 {
210 bool value2 = value ? true : false;
211 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
212 }
213 else
214 return false;
215
216 return true;
217 }
218
219 bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src,
220 wxAnyValueType* dstType,
221 wxAnyValueBuffer& dst) const
222 {
223 wxString value = GetValue(src);
224 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
225 {
226 wxAnyBaseIntType value2;
227 #ifdef wxLongLong_t
228 if ( !value.ToLongLong(&value2) )
229 #else
230 if ( !value.ToLong(&value2) )
231 #endif
232 return false;
233 wxAnyValueTypeImplInt::SetValue(value2, dst);
234 }
235 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
236 {
237 wxAnyBaseUintType value2;
238 #ifdef wxLongLong_t
239 if ( !value.ToULongLong(&value2) )
240 #else
241 if ( !value.ToULong(&value2) )
242 #endif
243 return false;
244 wxAnyValueTypeImplUint::SetValue(value2, dst);
245 }
246 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
247 {
248 double value2;
249 if ( !value.ToDouble(&value2) )
250 return false;
251 wxAnyValueTypeImplDouble::SetValue(value2, dst);
252 }
253 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
254 {
255 bool value2;
256 value.MakeLower();
257 if ( value == wxS("true") ||
258 value == wxS("yes") ||
259 value == wxS('1') )
260 value2 = true;
261 else if ( value == wxS("false") ||
262 value == wxS("no") ||
263 value == wxS('0') )
264 value2 = false;
265 else
266 return false;
267
268 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
269 }
270 else
271 return false;
272
273 return true;
274 }
275
276 bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src,
277 wxAnyValueType* dstType,
278 wxAnyValueBuffer& dst) const
279 {
280 bool value = GetValue(src);
281 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
282 {
283 wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value);
284 wxAnyValueTypeImplInt::SetValue(value2, dst);
285 }
286 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
287 {
288 wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value);
289 wxAnyValueTypeImplUint::SetValue(value2, dst);
290 }
291 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
292 {
293 wxString s;
294 if ( value )
295 s = wxS("true");
296 else
297 s = wxS("false");
298 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
299 }
300 else
301 return false;
302
303 return true;
304 }
305
306 bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src,
307 wxAnyValueType* dstType,
308 wxAnyValueBuffer& dst) const
309 {
310 double value = GetValue(src);
311 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
312 {
313 if ( value < UseIntMinF || value > UseIntMaxF )
314 return false;
315 wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
316 wxAnyValueTypeImplUint::SetValue(ul, dst);
317 }
318 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
319 {
320 if ( value < 0.0 || value > UseUintMaxF )
321 return false;
322 wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
323 wxAnyValueTypeImplUint::SetValue(ul, dst);
324 }
325 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
326 {
327 wxString s = wxString::Format(wxS("%.14g"), value);
328 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
329 }
330 else
331 return false;
332
333 return true;
334 }
335
336 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
337 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
338 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
339 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
340 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
341
342 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxDateTime>)
343 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxObject*>)
344 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxArrayString>)
345
346 //-------------------------------------------------------------------------
347 // wxAnyNullValueType implementation
348 //-------------------------------------------------------------------------
349
350 class wxAnyNullValue
351 {
352 private:
353 void* m_dummy;
354 };
355
356 template <>
357 class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType
358 {
359 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
360 public:
361 // Dummy implementations
362 virtual void DeleteValue(wxAnyValueBuffer& buf) const
363 {
364 wxUnusedVar(buf);
365 }
366
367 virtual void CopyBuffer(const wxAnyValueBuffer& src,
368 wxAnyValueBuffer& dst) const
369 {
370 wxUnusedVar(src);
371 wxUnusedVar(dst);
372 }
373
374 virtual bool ConvertValue(const wxAnyValueBuffer& src,
375 wxAnyValueType* dstType,
376 wxAnyValueBuffer& dst) const
377 {
378 wxUnusedVar(src);
379 wxUnusedVar(dstType);
380 wxUnusedVar(dst);
381 return false;
382 }
383
384 private:
385 };
386
387 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
388
389 wxAnyValueType* wxAnyNullValueType =
390 wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();
391
392 #endif // wxUSE_ANY