]> git.saurik.com Git - wxWidgets.git/blame - src/common/any.cpp
Committing modified version of jwiesemann's patch (see #11223):
[wxWidgets.git] / src / common / any.cpp
CommitLineData
39601a7f
VZ
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
31using 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//
46class wxAnyValueTypeGlobals
47{
48public:
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
63private:
64 wxVector<wxAnyValueType*> m_valueTypes;
65};
66
67static 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//
74class wxAnyValueTypeGlobalsManager : public wxModule
75{
76 DECLARE_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager)
77public:
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 }
90private:
91};
92
93IMPLEMENT_DYNAMIC_CLASS(wxAnyValueTypeGlobalsManager, wxModule)
94
95
96//-------------------------------------------------------------------------
97// wxAnyValueType
98//-------------------------------------------------------------------------
99
100wxAnyValueType::wxAnyValueType()
101{
102 if ( !g_wxAnyValueTypeGlobals )
103 g_wxAnyValueTypeGlobals = new wxAnyValueTypeGlobals();
104
105 g_wxAnyValueTypeGlobals->RegisterValueType(this);
106}
107
39601a7f
VZ
108//-------------------------------------------------------------------------
109// Dynamic conversion member functions
110//-------------------------------------------------------------------------
111
112//
113// Define integer minimum and maximum as helpers
114#ifdef wxLongLong_t
982d7f93
VZ
115 #define UseIntMin (wxINT64_MIN)
116 #define UseIntMax (wxINT64_MAX)
117 #define UseUintMax (wxUINT64_MAX)
39601a7f 118#else
982d7f93
VZ
119 #define UseIntMin (LONG_MIN)
120 #define UseIntMax (LONG_MAX)
121 #define UseUintMax (ULONG_MAX)
39601a7f
VZ
122#endif
123
982d7f93
VZ
124namespace
125{
126
39601a7f 127const double UseIntMinF = static_cast<double>(UseIntMin);
39601a7f
VZ
128const double UseIntMaxF = static_cast<double>(UseIntMax);
129const double UseUintMaxF = static_cast<double>(UseUintMax);
39601a7f 130
982d7f93 131} // anonymous namespace
39601a7f
VZ
132
133bool 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
171bool 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
215bool 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
272bool 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
302bool 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
332WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplInt)
333WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplUint)
334WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplString)
335WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<bool>)
336WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImplDouble)
337
c5fe6a5b
JS
338WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxDateTime>)
339//WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxObject*>)
340//WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxArrayString>)
341
39601a7f
VZ
342//-------------------------------------------------------------------------
343// wxAnyNullValueType implementation
344//-------------------------------------------------------------------------
345
346class wxAnyNullValue
347{
348private:
349 void* m_dummy;
350};
351
352template <>
353class wxAnyValueTypeImpl<wxAnyNullValue> : public wxAnyValueType
354{
355 WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
356public:
24985a9b 357 // Dummy implementations
39601a7f
VZ
358 virtual void DeleteValue(wxAnyValueBuffer& buf) const
359 {
24985a9b 360 wxUnusedVar(buf);
39601a7f
VZ
361 }
362
39601a7f
VZ
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
380private:
381};
382
383WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxAnyNullValue>)
384
385wxAnyValueType* wxAnyNullValueType =
386 wxAnyValueTypeImpl<wxAnyNullValue>::GetInstance();
387
388#endif // wxUSE_ANY