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
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_VARIANTBASE_H_
13 #define _WX_VARIANTBASE_H_
19 #include "wx/string.h"
20 #include "wx/arrstr.h"
25 #include "wx/datetime.h"
26 #endif // wxUSE_DATETIME
28 #include "wx/iosfwrap.h"
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.
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.
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
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.
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.
61 class WXDLLIMPEXP_BASE wxVariantData
63 friend class wxVariantBase
;
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; }
74 virtual bool Write(wxString
& WXUNUSED(str
)) const { return false; }
75 virtual bool Read(wxString
& WXUNUSED(str
)) { return false; }
77 // Override these to provide common functionality
78 virtual bool Eq(wxVariantData
& data
) const = 0;
80 // What type is it? Return a string name.
81 virtual wxString
GetType() const = 0;
83 // returns the type info of the content
84 virtual const wxTypeInfo
* GetTypeInfo() const = 0;
86 // If it based on wxObject return the ClassInfo.
87 virtual wxClassInfo
* GetValueClassInfo() { return NULL
; }
89 int GetRefCount() const
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() {}
109 template<typename T
> class wxVariantDataT
: public wxVariantData
112 wxVariantDataT(const T
& d
) : m_data(d
) {}
113 virtual ~wxVariantDataT() {}
115 // get a ref to the stored data
116 T
& Get() { return m_data
; }
118 // get a const ref to the stored data
119 const T
& Get() const { return m_data
; }
122 void Set(const T
& d
) { m_data
= d
; }
124 // Override these to provide common functionality
125 virtual bool Eq(wxVariantData
& WXUNUSED(data
)) const
126 { return false; /* FIXME!! */ }
128 // What type is it? Return a string name.
129 virtual wxString
GetType() const
130 { return GetTypeInfo()->GetTypeName(); }
132 // return a heap allocated duplicate
133 //virtual wxVariantData* Clone() const { return new wxVariantDataT<T>( Get() ); }
135 // returns the type info of the contentc
136 virtual const wxTypeInfo
* GetTypeInfo() const { return wxGetTypeInfo( (T
*) NULL
); }
144 * wxVariantBase can store any kind of data, but has some basic types
148 class WXDLLIMPEXP_BASE wxVariantBase
152 wxVariantBase(const wxVariantBase
& variant
);
153 wxVariantBase(wxVariantData
* data
, const wxString
& name
= wxEmptyString
);
156 wxVariantBase(const T
& data
, const wxString
& name
= wxEmptyString
) :
157 m_data(new wxVariantDataT
<T
>(data
)), m_name(name
) {}
159 virtual ~wxVariantBase();
161 // generic assignment
162 void operator= (const wxVariantBase
& variant
);
164 // Assignment using data, e.g.
165 // myVariant = new wxStringVariantData("hello");
166 void operator= (wxVariantData
* variantData
);
168 bool operator== (const wxVariantBase
& variant
) const;
169 bool operator!= (const wxVariantBase
& variant
) const;
172 inline void SetName(const wxString
& name
) { m_name
= name
; }
173 inline const wxString
& GetName() const { return m_name
; }
175 // Tests whether there is data
178 // FIXME: used by wxVariantBase code but is nice wording...
179 bool IsEmpty() const { return IsNull(); }
181 // For compatibility with wxWidgets <= 2.6, this doesn't increase
183 wxVariantData
* GetData() const { return m_data
; }
184 void SetData(wxVariantData
* data
) ;
186 // make a 'clone' of the object
187 void Ref(const wxVariantBase
& clone
);
189 // destroy a reference
192 // Make NULL (i.e. delete the data)
195 // write contents to a string (e.g. for debugging)
196 wxString
MakeString() const;
198 // Delete data and name
201 // Returns a string representing the type of the variant,
202 // e.g. "string", "bool", "stringlist", "list", "double", "long"
203 wxString
GetType() const;
205 bool IsType(const wxString
& type
) const;
206 bool IsValueKindOf(const wxClassInfo
* type
) const;
208 // FIXME wxXTI methods:
210 // get the typeinfo of the stored object
211 const wxTypeInfo
* GetTypeInfo() const
215 return m_data
->GetTypeInfo();
218 // get a ref to the stored data
219 template<typename T
> T
& Get(wxTEMPLATED_MEMBER_FIX(T
))
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();
228 // get a const ref to the stored data
229 template<typename T
> const T
& Get(wxTEMPLATED_MEMBER_FIX(T
)) const
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();
238 template<typename T
> bool HasData(wxTEMPLATED_MEMBER_FIX(T
)) const
240 const wxVariantDataT
<T
> *dataptr
=
241 wx_dynamic_cast(const wxVariantDataT
<T
>*, m_data
);
242 return dataptr
!= NULL
;
245 // returns this value as string
246 wxString
GetAsString() const;
248 // gets the stored data casted to a wxObject*,
249 // returning NULL if cast is not possible
250 wxObject
* GetAsObject();
253 wxVariantData
* m_data
;
257 #include "wx/dynarray.h"
258 WX_DECLARE_OBJARRAY_WITH_DECL(wxVariantBase
, wxVariantBaseArray
, class WXDLLIMPEXP_BASE
);
261 // templated streaming, every type must have their specialization for these methods
264 void wxStringReadValue( const wxString
&s
, T
&data
);
267 void wxStringWriteValue( wxString
&s
, const T
&data
);
270 void wxToStringConverter( const wxVariantBase
&v
, wxString
&s
wxTEMPLATED_FUNCTION_FIX(T
)) \
271 { wxStringWriteValue( s
, v
.wxTEMPLATED_MEMBER_CALL(Get
, T
) ); }
274 void wxFromStringConverter( const wxString
&s
, wxVariantBase
&v
wxTEMPLATED_FUNCTION_FIX(T
)) \
275 { T d
; wxStringReadValue( s
, d
); v
= wxVariantBase(d
); }
278 #endif // wxUSE_VARIANT
279 #endif // _WX_VARIANTBASE_H_