variantbase.h 8.2 KB

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