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