]>
Commit | Line | Data |
---|---|---|
e1d3601a PC |
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_ |