Fix UseUintMax definition used by wxAny for VC6.
[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 #define UseIntMin (wxINT64_MIN)
116 #define UseIntMax (wxINT64_MAX)
117 #define UseUintMax (wxUINT64_MAX)
118 #else
119 #define UseIntMin (LONG_MIN)
120 #define UseIntMax (LONG_MAX)
121 #define UseUintMax (ULONG_MAX)
122 #endif
123
124 namespace
125 {
126
127 const double UseIntMinF = static_cast<double>(UseIntMin);
128 const double UseIntMaxF = static_cast<double>(UseIntMax);
129 const double UseUintMaxF = static_cast<double>(UseUintMax);
130
131 } // anonymous namespace
132
133 bool wxAnyValueTypeImplInt::ConvertValue(const wxAnyValueBuffer& src,
134 wxAnyValueType* dstType,
135 wxAnyValueBuffer& dst) const
136 {
137 wxAnyBaseIntType value = GetValue(src);
138 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
139 {
140 #ifdef wxLongLong_t
141 wxLongLong ll(value);
142 wxString s = ll.ToString();
143 #else
144 wxString s = wxString::Format(wxS("%ld"), (long)value);
145 #endif
146 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
147 }
148 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
149 {
150 if ( value < 0 )
151 return false;
152 wxAnyBaseUintType ul = (wxAnyBaseUintType) value;
153 wxAnyValueTypeImplUint::SetValue(ul, dst);
154 }
155 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
156 {
157 double value2 = static_cast<double>(value);
158 wxAnyValueTypeImplDouble::SetValue(value2, dst);
159 }
160 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
161 {
162 bool value2 = value ? true : false;
163 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
164 }
165 else
166 return false;
167
168 return true;
169 }
170
171 bool wxAnyValueTypeImplUint::ConvertValue(const wxAnyValueBuffer& src,
172 wxAnyValueType* dstType,
173 wxAnyValueBuffer& dst) const
174 {
175 wxAnyBaseUintType value = GetValue(src);
176 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
177 {
178 #ifdef wxLongLong_t
179 wxULongLong ull(value);
180 wxString s = ull.ToString();
181 #else
182 wxString s = wxString::Format(wxS("%lu"), (long)value);
183 #endif
184 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
185 }
186 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
187 {
188 if ( value > UseIntMax )
189 return false;
190 wxAnyBaseIntType l = (wxAnyBaseIntType) value;
191 wxAnyValueTypeImplInt::SetValue(l, dst);
192 }
193 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
194 {
195 #ifndef __VISUALC6__
196 double value2 = static_cast<double>(value);
197 #else
198 // VC6 doesn't implement conversion from unsigned __int64 to double
199 wxAnyBaseIntType value0 = static_cast<wxAnyBaseIntType>(value);
200 double value2 = static_cast<double>(value0);
201 #endif
202 wxAnyValueTypeImplDouble::SetValue(value2, dst);
203 }
204 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
205 {
206 bool value2 = value ? true : false;
207 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
208 }
209 else
210 return false;
211
212 return true;
213 }
214
215 bool wxAnyValueTypeImplString::ConvertValue(const wxAnyValueBuffer& src,
216 wxAnyValueType* dstType,
217 wxAnyValueBuffer& dst) const
218 {
219 wxString value = GetValue(src);
220 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
221 {
222 wxAnyBaseIntType value2;
223 #ifdef wxLongLong_t
224 if ( !value.ToLongLong(&value2) )
225 #else
226 if ( !value.ToLong(&value2) )
227 #endif
228 return false;
229 wxAnyValueTypeImplInt::SetValue(value2, dst);
230 }
231 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
232 {
233 wxAnyBaseUintType value2;
234 #ifdef wxLongLong_t
235 if ( !value.ToULongLong(&value2) )
236 #else
237 if ( !value.ToULong(&value2) )
238 #endif
239 return false;
240 wxAnyValueTypeImplUint::SetValue(value2, dst);
241 }
242 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, double) )
243 {
244 double value2;
245 if ( !value.ToDouble(&value2) )
246 return false;
247 wxAnyValueTypeImplDouble::SetValue(value2, dst);
248 }
249 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, bool) )
250 {
251 bool value2;
252 value.MakeLower();
253 if ( value == wxS("true") ||
254 value == wxS("yes") ||
255 value == wxS('1') )
256 value2 = true;
257 else if ( value == wxS("false") ||
258 value == wxS("no") ||
259 value == wxS('0') )
260 value2 = false;
261 else
262 return false;
263
264 wxAnyValueTypeImpl<bool>::SetValue(value2, dst);
265 }
266 else
267 return false;
268
269 return true;
270 }
271
272 bool wxAnyValueTypeImpl<bool>::ConvertValue(const wxAnyValueBuffer& src,
273 wxAnyValueType* dstType,
274 wxAnyValueBuffer& dst) const
275 {
276 bool value = GetValue(src);
277 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
278 {
279 wxAnyBaseIntType value2 = static_cast<wxAnyBaseIntType>(value);
280 wxAnyValueTypeImplInt::SetValue(value2, dst);
281 }
282 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
283 {
284 wxAnyBaseIntType value2 = static_cast<wxAnyBaseUintType>(value);
285 wxAnyValueTypeImplUint::SetValue(value2, dst);
286 }
287 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
288 {
289 wxString s;
290 if ( value )
291 s = wxS("true");
292 else
293 s = wxS("false");
294 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
295 }
296 else
297 return false;
298
299 return true;
300 }
301
302 bool wxAnyValueTypeImplDouble::ConvertValue(const wxAnyValueBuffer& src,
303 wxAnyValueType* dstType,
304 wxAnyValueBuffer& dst) const
305 {
306 double value = GetValue(src);
307 if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseIntType) )
308 {
309 if ( value < UseIntMinF || value > UseIntMaxF )
310 return false;
311 wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
312 wxAnyValueTypeImplUint::SetValue(ul, dst);
313 }
314 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxAnyBaseUintType) )
315 {
316 if ( value < 0.0 || value > UseUintMaxF )
317 return false;
318 wxAnyBaseUintType ul = static_cast<wxAnyBaseUintType>(value);
319 wxAnyValueTypeImplUint::SetValue(ul, dst);
320 }
321 else if ( wxANY_VALUE_TYPE_CHECK_TYPE(dstType, wxString) )
322 {
323 wxString s = wxString::Format(wxS("%.14g"), value);
324 wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
325 }
326 else
327 return false;
328
329 return true;
330 }
331
332 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
333 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
334 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
335 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
336 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
337
338 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxDateTime>)
339 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxObject*>)
340 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxArrayString>)
341
342 //-------------------------------------------------------------------------
343 // wxAnyNullValueType implementation
344 //-------------------------------------------------------------------------
345
346 class wxAnyNullValue
347 {
348 private:
349 void* m_dummy;
350 };
351
352 template <>
353 class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType
354 {
355 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
356 public:
357 // Dummy implementations
358 virtual void DeleteValue(wxAnyValueBuffer& buf) const
359 {
360 wxUnusedVar(buf);
361 }
362
363 virtual void CopyBuffer(const wxAnyValueBuffer& src,
364 wxAnyValueBuffer& dst) const
365 {
366 wxUnusedVar(src);
367 wxUnusedVar(dst);
368 }
369
370 virtual bool ConvertValue(const wxAnyValueBuffer& src,
371 wxAnyValueType* dstType,
372 wxAnyValueBuffer& dst) const
373 {
374 wxUnusedVar(src);
375 wxUnusedVar(dstType);
376 wxUnusedVar(dst);
377 return false;
378 }
379
380 private:
381 };
382
383 WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
384
385 wxAnyValueType* wxAnyNullValueType =
386 wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();
387
388 #endif // wxUSE_ANY