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
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_VARIANTBASE_H_
12 #define _WX_VARIANTBASE_H_
18 #include "wx/string.h"
19 #include "wx/arrstr.h"
24 #include "wx/datetime.h"
25 #endif // wxUSE_DATETIME
27 #include "wx/iosfwrap.h"
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.
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.
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
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.
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.
60 class WXDLLIMPEXP_BASE wxVariantData
62 friend class wxVariantBase
;
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; }
73 virtual bool Write(wxString
& WXUNUSED(str
)) const { return false; }
74 virtual bool Read(wxString
& WXUNUSED(str
)) { return false; }
76 // Override these to provide common functionality
77 virtual bool Eq(wxVariantData
& data
) const = 0;
79 // What type is it? Return a string name.
80 virtual wxString
GetType() const = 0;
82 // returns the type info of the content
83 virtual const wxTypeInfo
* GetTypeInfo() const = 0;
85 // If it based on wxObject return the ClassInfo.
86 virtual wxClassInfo
* GetValueClassInfo() { return NULL
; }
88 int GetRefCount() const
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() {}
108 template<typename T
> class wxVariantDataT
: public wxVariantData
111 wxVariantDataT(const T
& d
) : m_data(d
) {}
112 virtual ~wxVariantDataT() {}
114 // get a ref to the stored data
115 T
& Get() { return m_data
; }
117 // get a const ref to the stored data
118 const T
& Get() const { return m_data
; }
121 void Set(const T
& d
) { m_data
= d
; }
123 // Override these to provide common functionality
124 virtual bool Eq(wxVariantData
& WXUNUSED(data
)) const
125 { return false; /* FIXME!! */ }
127 // What type is it? Return a string name.
128 virtual wxString
GetType() const
129 { return GetTypeInfo()->GetTypeName(); }
131 // return a heap allocated duplicate
132 //virtual wxVariantData* Clone() const { return new wxVariantDataT<T>( Get() ); }
134 // returns the type info of the contentc
135 virtual const wxTypeInfo
* GetTypeInfo() const { return wxGetTypeInfo( (T
*) NULL
); }
143 * wxVariantBase can store any kind of data, but has some basic types
147 class WXDLLIMPEXP_BASE wxVariantBase
151 wxVariantBase(const wxVariantBase
& variant
);
152 wxVariantBase(wxVariantData
* data
, const wxString
& name
= wxEmptyString
);
155 wxVariantBase(const T
& data
, const wxString
& name
= wxEmptyString
) :
156 m_data(new wxVariantDataT
<T
>(data
)), m_name(name
) {}
158 virtual ~wxVariantBase();
160 // generic assignment
161 void operator= (const wxVariantBase
& variant
);
163 // Assignment using data, e.g.
164 // myVariant = new wxStringVariantData("hello");
165 void operator= (wxVariantData
* variantData
);
167 bool operator== (const wxVariantBase
& variant
) const;
168 bool operator!= (const wxVariantBase
& variant
) const;
171 inline void SetName(const wxString
& name
) { m_name
= name
; }
172 inline const wxString
& GetName() const { return m_name
; }
174 // Tests whether there is data
177 // FIXME: used by wxVariantBase code but is nice wording...
178 bool IsEmpty() const { return IsNull(); }
180 // For compatibility with wxWidgets <= 2.6, this doesn't increase
182 wxVariantData
* GetData() const { return m_data
; }
183 void SetData(wxVariantData
* data
) ;
185 // make a 'clone' of the object
186 void Ref(const wxVariantBase
& clone
);
188 // destroy a reference
191 // Make NULL (i.e. delete the data)
194 // write contents to a string (e.g. for debugging)
195 wxString
MakeString() const;
197 // Delete data and name
200 // Returns a string representing the type of the variant,
201 // e.g. "string", "bool", "stringlist", "list", "double", "long"
202 wxString
GetType() const;
204 bool IsType(const wxString
& type
) const;
205 bool IsValueKindOf(const wxClassInfo
* type
) const;
207 // FIXME wxXTI methods:
209 // get the typeinfo of the stored object
210 const wxTypeInfo
* GetTypeInfo() const
214 return m_data
->GetTypeInfo();
217 // get a ref to the stored data
218 template<typename T
> T
& Get(wxTEMPLATED_MEMBER_FIX(T
))
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();
227 // get a const ref to the stored data
228 template<typename T
> const T
& Get(wxTEMPLATED_MEMBER_FIX(T
)) const
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();
237 template<typename T
> bool HasData(wxTEMPLATED_MEMBER_FIX(T
)) const
239 const wxVariantDataT
<T
> *dataptr
=
240 wx_dynamic_cast(const wxVariantDataT
<T
>*, m_data
);
241 return dataptr
!= NULL
;
244 // returns this value as string
245 wxString
GetAsString() const;
247 // gets the stored data casted to a wxObject*,
248 // returning NULL if cast is not possible
249 wxObject
* GetAsObject();
252 wxVariantData
* m_data
;
256 #include "wx/dynarray.h"
257 WX_DECLARE_OBJARRAY_WITH_DECL(wxVariantBase
, wxVariantBaseArray
, class WXDLLIMPEXP_BASE
);
260 // templated streaming, every type must have their specialization for these methods
263 void wxStringReadValue( const wxString
&s
, T
&data
);
266 void wxStringWriteValue( wxString
&s
, const T
&data
);
269 void wxToStringConverter( const wxVariantBase
&v
, wxString
&s
wxTEMPLATED_FUNCTION_FIX(T
)) \
270 { wxStringWriteValue( s
, v
.wxTEMPLATED_MEMBER_CALL(Get
, T
) ); }
273 void wxFromStringConverter( const wxString
&s
, wxVariantBase
&v
wxTEMPLATED_FUNCTION_FIX(T
)) \
274 { T d
; wxStringReadValue( s
, d
); v
= wxVariantBase(d
); }
277 #endif // wxUSE_VARIANT
278 #endif // _WX_VARIANTBASE_H_