]> git.saurik.com Git - wxWidgets.git/blob - include/wx/variantbase.h
using Run of base class
[wxWidgets.git] / include / wx / variantbase.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/variantbase.h
3 // Purpose: wxVariantBase class, a minimal version of wxVariant used by XTI
4 // Author: Julian Smart
5 // Modified by: Francesco Montorsi
6 // Created: 10/09/98
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifndef _WX_VARIANTBASE_H_
12 #define _WX_VARIANTBASE_H_
13
14 #include "wx/defs.h"
15
16 #if wxUSE_VARIANT
17
18 #include "wx/string.h"
19 #include "wx/arrstr.h"
20 #include "wx/cpp.h"
21 #include <typeinfo>
22
23 #if wxUSE_DATETIME
24 #include "wx/datetime.h"
25 #endif // wxUSE_DATETIME
26
27 #include "wx/iosfwrap.h"
28
29 class wxTypeInfo;
30 class wxObject;
31 class wxClassInfo;
32
33 /*
34 * wxVariantData stores the actual data in a wxVariant object,
35 * to allow it to store any type of data.
36 * Derive from this to provide custom data handling.
37 *
38 * NB: To prevent addition of extra vtbl pointer to wxVariantData,
39 * we don't multiple-inherit from wxObjectRefData. Instead,
40 * we simply replicate the wxObject ref-counting scheme.
41 *
42 * NB: When you construct a wxVariantData, it will have refcount
43 * of one. Refcount will not be further increased when
44 * it is passed to wxVariant. This simulates old common
45 * scenario where wxVariant took ownership of wxVariantData
46 * passed to it.
47 * If you create wxVariantData for other reasons than passing
48 * it to wxVariant, technically you are not required to call
49 * DecRef() before deleting it.
50 *
51 * TODO: in order to replace wxPropertyValue, we would need
52 * to consider adding constructors that take pointers to C++ variables,
53 * or removing that functionality from the wxProperty library.
54 * Essentially wxPropertyValue takes on some of the wxValidator functionality
55 * by storing pointers and not just actual values, allowing update of C++ data
56 * to be handled automatically. Perhaps there's another way of doing this without
57 * overloading wxVariant with unnecessary functionality.
58 */
59
60 class WXDLLIMPEXP_BASE wxVariantData
61 {
62 friend class wxVariantBase;
63
64 public:
65 wxVariantData()
66 : m_count(1)
67 { }
68
69 #if wxUSE_STD_IOSTREAM
70 virtual bool Write(wxSTD ostream& WXUNUSED(str)) const { return false; }
71 virtual bool Read(wxSTD istream& WXUNUSED(str)) { return false; }
72 #endif
73 virtual bool Write(wxString& WXUNUSED(str)) const { return false; }
74 virtual bool Read(wxString& WXUNUSED(str)) { return false; }
75
76 // Override these to provide common functionality
77 virtual bool Eq(wxVariantData& data) const = 0;
78
79 // What type is it? Return a string name.
80 virtual wxString GetType() const = 0;
81
82 // returns the type info of the content
83 virtual const wxTypeInfo* GetTypeInfo() const = 0;
84
85 // If it based on wxObject return the ClassInfo.
86 virtual wxClassInfo* GetValueClassInfo() { return NULL; }
87
88 int GetRefCount() const
89 { return m_count; }
90 void IncRef()
91 { m_count++; }
92 void DecRef()
93 {
94 if ( --m_count == 0 )
95 delete this;
96 }
97
98 protected:
99 // Protected dtor should make some incompatible code
100 // break more louder. That is, they should do data->DecRef()
101 // instead of delete data.
102 virtual ~wxVariantData() {}
103
104 private:
105 int m_count;
106 };
107
108 template<typename T> class wxVariantDataT : public wxVariantData
109 {
110 public:
111 wxVariantDataT(const T& d) : m_data(d) {}
112 virtual ~wxVariantDataT() {}
113
114 // get a ref to the stored data
115 T & Get() { return m_data; }
116
117 // get a const ref to the stored data
118 const T & Get() const { return m_data; }
119
120 // set the data
121 void Set(const T& d) { m_data = d; }
122
123 // Override these to provide common functionality
124 virtual bool Eq(wxVariantData& WXUNUSED(data)) const
125 { return false; /* FIXME!! */ }
126
127 // What type is it? Return a string name.
128 virtual wxString GetType() const
129 { return GetTypeInfo()->GetTypeName(); }
130
131 // return a heap allocated duplicate
132 //virtual wxVariantData* Clone() const { return new wxVariantDataT<T>( Get() ); }
133
134 // returns the type info of the contentc
135 virtual const wxTypeInfo* GetTypeInfo() const { return wxGetTypeInfo( (T*) NULL ); }
136
137 private:
138 T m_data;
139 };
140
141
142 /*
143 * wxVariantBase can store any kind of data, but has some basic types
144 * built in.
145 */
146
147 class WXDLLIMPEXP_BASE wxVariantBase
148 {
149 public:
150 wxVariantBase();
151 wxVariantBase(const wxVariantBase& variant);
152 wxVariantBase(wxVariantData* data, const wxString& name = wxEmptyString);
153
154 template<typename T>
155 wxVariantBase(const T& data, const wxString& name = wxEmptyString) :
156 m_data(new wxVariantDataT<T>(data)), m_name(name) {}
157
158 virtual ~wxVariantBase();
159
160 // generic assignment
161 void operator= (const wxVariantBase& variant);
162
163 // Assignment using data, e.g.
164 // myVariant = new wxStringVariantData("hello");
165 void operator= (wxVariantData* variantData);
166
167 bool operator== (const wxVariantBase& variant) const;
168 bool operator!= (const wxVariantBase& variant) const;
169
170 // Sets/gets name
171 inline void SetName(const wxString& name) { m_name = name; }
172 inline const wxString& GetName() const { return m_name; }
173
174 // Tests whether there is data
175 bool IsNull() const;
176
177 // FIXME: used by wxVariantBase code but is nice wording...
178 bool IsEmpty() const { return IsNull(); }
179
180 // For compatibility with wxWidgets <= 2.6, this doesn't increase
181 // reference count.
182 wxVariantData* GetData() const { return m_data; }
183 void SetData(wxVariantData* data) ;
184
185 // make a 'clone' of the object
186 void Ref(const wxVariantBase& clone);
187
188 // destroy a reference
189 void UnRef();
190
191 // Make NULL (i.e. delete the data)
192 void MakeNull();
193
194 // write contents to a string (e.g. for debugging)
195 wxString MakeString() const;
196
197 // Delete data and name
198 void Clear();
199
200 // Returns a string representing the type of the variant,
201 // e.g. "string", "bool", "stringlist", "list", "double", "long"
202 wxString GetType() const;
203
204 bool IsType(const wxString& type) const;
205 bool IsValueKindOf(const wxClassInfo* type) const;
206
207 // FIXME wxXTI methods:
208
209 // get the typeinfo of the stored object
210 const wxTypeInfo* GetTypeInfo() const
211 {
212 if (!m_data)
213 return NULL;
214 return m_data->GetTypeInfo();
215 }
216
217 // get a ref to the stored data
218 template<typename T> T& Get(wxTEMPLATED_MEMBER_FIX(T))
219 {
220 wxVariantDataT<T> *dataptr =
221 wx_dynamic_cast(wxVariantDataT<T>*, m_data);
222 wxASSERT_MSG( dataptr,
223 wxString::Format(wxT("Cast to %s not possible"), typeid(T).name()) );
224 return dataptr->Get();
225 }
226
227 // get a const ref to the stored data
228 template<typename T> const T& Get(wxTEMPLATED_MEMBER_FIX(T)) const
229 {
230 const wxVariantDataT<T> *dataptr =
231 wx_dynamic_cast(const wxVariantDataT<T>*, m_data);
232 wxASSERT_MSG( dataptr,
233 wxString::Format(wxT("Cast to %s not possible"), typeid(T).name()) );
234 return dataptr->Get();
235 }
236
237 template<typename T> bool HasData(wxTEMPLATED_MEMBER_FIX(T)) const
238 {
239 const wxVariantDataT<T> *dataptr =
240 wx_dynamic_cast(const wxVariantDataT<T>*, m_data);
241 return dataptr != NULL;
242 }
243
244 // returns this value as string
245 wxString GetAsString() const;
246
247 // gets the stored data casted to a wxObject*,
248 // returning NULL if cast is not possible
249 wxObject* GetAsObject();
250
251 protected:
252 wxVariantData* m_data;
253 wxString m_name;
254 };
255
256 #include "wx/dynarray.h"
257 WX_DECLARE_OBJARRAY_WITH_DECL(wxVariantBase, wxVariantBaseArray, class WXDLLIMPEXP_BASE);
258
259
260 // templated streaming, every type must have their specialization for these methods
261
262 template<typename T>
263 void wxStringReadValue( const wxString &s, T &data );
264
265 template<typename T>
266 void wxStringWriteValue( wxString &s, const T &data);
267
268 template<typename T>
269 void wxToStringConverter( const wxVariantBase &v, wxString &s wxTEMPLATED_FUNCTION_FIX(T)) \
270 { wxStringWriteValue( s, v.wxTEMPLATED_MEMBER_CALL(Get, T) ); }
271
272 template<typename T>
273 void wxFromStringConverter( const wxString &s, wxVariantBase &v wxTEMPLATED_FUNCTION_FIX(T)) \
274 { T d; wxStringReadValue( s, d ); v = wxVariantBase(d); }
275
276
277 #endif // wxUSE_VARIANT
278 #endif // _WX_VARIANTBASE_H_