variant.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/variant.h
  3. // Purpose: wxVariant class, container for any type
  4. // Author: Julian Smart
  5. // Modified by:
  6. // Created: 10/09/98
  7. // Copyright: (c) Julian Smart
  8. // Licence: wxWindows licence
  9. /////////////////////////////////////////////////////////////////////////////
  10. #ifndef _WX_VARIANT_H_
  11. #define _WX_VARIANT_H_
  12. #include "wx/defs.h"
  13. #if wxUSE_VARIANT
  14. #include "wx/object.h"
  15. #include "wx/string.h"
  16. #include "wx/arrstr.h"
  17. #include "wx/list.h"
  18. #include "wx/cpp.h"
  19. #include "wx/longlong.h"
  20. #if wxUSE_DATETIME
  21. #include "wx/datetime.h"
  22. #endif // wxUSE_DATETIME
  23. #include "wx/iosfwrap.h"
  24. class wxAny;
  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: When you construct a wxVariantData, it will have refcount
  31. * of one. Refcount will not be further increased when
  32. * it is passed to wxVariant. This simulates old common
  33. * scenario where wxVariant took ownership of wxVariantData
  34. * passed to it.
  35. * If you create wxVariantData for other reasons than passing
  36. * it to wxVariant, technically you are not required to call
  37. * DecRef() before deleting it.
  38. *
  39. * TODO: in order to replace wxPropertyValue, we would need
  40. * to consider adding constructors that take pointers to C++ variables,
  41. * or removing that functionality from the wxProperty library.
  42. * Essentially wxPropertyValue takes on some of the wxValidator functionality
  43. * by storing pointers and not just actual values, allowing update of C++ data
  44. * to be handled automatically. Perhaps there's another way of doing this without
  45. * overloading wxVariant with unnecessary functionality.
  46. */
  47. class WXDLLIMPEXP_BASE wxVariantData : public wxObjectRefData
  48. {
  49. friend class wxVariant;
  50. public:
  51. wxVariantData() { }
  52. // Override these to provide common functionality
  53. virtual bool Eq(wxVariantData& data) const = 0;
  54. #if wxUSE_STD_IOSTREAM
  55. virtual bool Write(wxSTD ostream& WXUNUSED(str)) const { return false; }
  56. #endif
  57. virtual bool Write(wxString& WXUNUSED(str)) const { return false; }
  58. #if wxUSE_STD_IOSTREAM
  59. virtual bool Read(wxSTD istream& WXUNUSED(str)) { return false; }
  60. #endif
  61. virtual bool Read(wxString& WXUNUSED(str)) { return false; }
  62. // What type is it? Return a string name.
  63. virtual wxString GetType() const = 0;
  64. // If it based on wxObject return the ClassInfo.
  65. virtual wxClassInfo* GetValueClassInfo() { return NULL; }
  66. // Implement this to make wxVariant::UnShare work. Returns
  67. // a copy of the data.
  68. virtual wxVariantData* Clone() const { return NULL; }
  69. #if wxUSE_ANY
  70. // Converts value to wxAny, if possible. Return true if successful.
  71. virtual bool GetAsAny(wxAny* WXUNUSED(any)) const { return false; }
  72. #endif
  73. protected:
  74. // Protected dtor should make some incompatible code
  75. // break more louder. That is, they should do data->DecRef()
  76. // instead of delete data.
  77. virtual ~wxVariantData() { }
  78. };
  79. /*
  80. * wxVariant can store any kind of data, but has some basic types
  81. * built in.
  82. */
  83. class WXDLLIMPEXP_FWD_BASE wxVariant;
  84. WX_DECLARE_LIST_WITH_DECL(wxVariant, wxVariantList, class WXDLLIMPEXP_BASE);
  85. class WXDLLIMPEXP_BASE wxVariant: public wxObject
  86. {
  87. public:
  88. wxVariant();
  89. wxVariant(const wxVariant& variant);
  90. wxVariant(wxVariantData* data, const wxString& name = wxEmptyString);
  91. #if wxUSE_ANY
  92. wxVariant(const wxAny& any);
  93. #endif
  94. virtual ~wxVariant();
  95. // generic assignment
  96. void operator= (const wxVariant& variant);
  97. // Assignment using data, e.g.
  98. // myVariant = new wxStringVariantData("hello");
  99. void operator= (wxVariantData* variantData);
  100. bool operator== (const wxVariant& variant) const;
  101. bool operator!= (const wxVariant& variant) const;
  102. // Sets/gets name
  103. inline void SetName(const wxString& name) { m_name = name; }
  104. inline const wxString& GetName() const { return m_name; }
  105. // Tests whether there is data
  106. bool IsNull() const;
  107. // For compatibility with wxWidgets <= 2.6, this doesn't increase
  108. // reference count.
  109. wxVariantData* GetData() const
  110. {
  111. return (wxVariantData*) m_refData;
  112. }
  113. void SetData(wxVariantData* data) ;
  114. // make a 'clone' of the object
  115. void Ref(const wxVariant& clone) { wxObject::Ref(clone); }
  116. // ensure that the data is exclusive to this variant, and not shared
  117. bool Unshare();
  118. // Make NULL (i.e. delete the data)
  119. void MakeNull();
  120. // Delete data and name
  121. void Clear();
  122. // Returns a string representing the type of the variant,
  123. // e.g. "string", "bool", "stringlist", "list", "double", "long"
  124. wxString GetType() const;
  125. bool IsType(const wxString& type) const;
  126. bool IsValueKindOf(const wxClassInfo* type) const;
  127. // write contents to a string (e.g. for debugging)
  128. wxString MakeString() const;
  129. #if wxUSE_ANY
  130. wxAny GetAny() const;
  131. #endif
  132. // double
  133. wxVariant(double val, const wxString& name = wxEmptyString);
  134. bool operator== (double value) const;
  135. bool operator!= (double value) const;
  136. void operator= (double value) ;
  137. inline operator double () const { return GetDouble(); }
  138. inline double GetReal() const { return GetDouble(); }
  139. double GetDouble() const;
  140. // long
  141. wxVariant(long val, const wxString& name = wxEmptyString);
  142. wxVariant(int val, const wxString& name = wxEmptyString);
  143. wxVariant(short val, const wxString& name = wxEmptyString);
  144. bool operator== (long value) const;
  145. bool operator!= (long value) const;
  146. void operator= (long value) ;
  147. inline operator long () const { return GetLong(); }
  148. inline long GetInteger() const { return GetLong(); }
  149. long GetLong() const;
  150. // bool
  151. wxVariant(bool val, const wxString& name = wxEmptyString);
  152. bool operator== (bool value) const;
  153. bool operator!= (bool value) const;
  154. void operator= (bool value) ;
  155. inline operator bool () const { return GetBool(); }
  156. bool GetBool() const ;
  157. // wxDateTime
  158. #if wxUSE_DATETIME
  159. wxVariant(const wxDateTime& val, const wxString& name = wxEmptyString);
  160. bool operator== (const wxDateTime& value) const;
  161. bool operator!= (const wxDateTime& value) const;
  162. void operator= (const wxDateTime& value) ;
  163. inline operator wxDateTime () const { return GetDateTime(); }
  164. wxDateTime GetDateTime() const;
  165. #endif
  166. // wxString
  167. wxVariant(const wxString& val, const wxString& name = wxEmptyString);
  168. // these overloads are necessary to prevent the compiler from using bool
  169. // version instead of wxString one:
  170. wxVariant(const char* val, const wxString& name = wxEmptyString);
  171. wxVariant(const wchar_t* val, const wxString& name = wxEmptyString);
  172. wxVariant(const wxCStrData& val, const wxString& name = wxEmptyString);
  173. wxVariant(const wxScopedCharBuffer& val, const wxString& name = wxEmptyString);
  174. wxVariant(const wxScopedWCharBuffer& val, const wxString& name = wxEmptyString);
  175. bool operator== (const wxString& value) const;
  176. bool operator!= (const wxString& value) const;
  177. wxVariant& operator=(const wxString& value);
  178. // these overloads are necessary to prevent the compiler from using bool
  179. // version instead of wxString one:
  180. wxVariant& operator=(const char* value)
  181. { return *this = wxString(value); }
  182. wxVariant& operator=(const wchar_t* value)
  183. { return *this = wxString(value); }
  184. wxVariant& operator=(const wxCStrData& value)
  185. { return *this = value.AsString(); }
  186. template<typename T>
  187. wxVariant& operator=(const wxScopedCharTypeBuffer<T>& value)
  188. { return *this = value.data(); }
  189. inline operator wxString () const { return MakeString(); }
  190. wxString GetString() const;
  191. #if wxUSE_STD_STRING
  192. wxVariant(const std::string& val, const wxString& name = wxEmptyString);
  193. bool operator==(const std::string& value) const
  194. { return operator==(wxString(value)); }
  195. bool operator!=(const std::string& value) const
  196. { return operator!=(wxString(value)); }
  197. wxVariant& operator=(const std::string& value)
  198. { return operator=(wxString(value)); }
  199. operator std::string() const { return (operator wxString()).ToStdString(); }
  200. wxVariant(const wxStdWideString& val, const wxString& name = wxEmptyString);
  201. bool operator==(const wxStdWideString& value) const
  202. { return operator==(wxString(value)); }
  203. bool operator!=(const wxStdWideString& value) const
  204. { return operator!=(wxString(value)); }
  205. wxVariant& operator=(const wxStdWideString& value)
  206. { return operator=(wxString(value)); }
  207. operator wxStdWideString() const { return (operator wxString()).ToStdWstring(); }
  208. #endif // wxUSE_STD_STRING
  209. // wxUniChar
  210. wxVariant(const wxUniChar& val, const wxString& name = wxEmptyString);
  211. wxVariant(const wxUniCharRef& val, const wxString& name = wxEmptyString);
  212. wxVariant(char val, const wxString& name = wxEmptyString);
  213. wxVariant(wchar_t val, const wxString& name = wxEmptyString);
  214. bool operator==(const wxUniChar& value) const;
  215. bool operator==(const wxUniCharRef& value) const { return *this == wxUniChar(value); }
  216. bool operator==(char value) const { return *this == wxUniChar(value); }
  217. bool operator==(wchar_t value) const { return *this == wxUniChar(value); }
  218. bool operator!=(const wxUniChar& value) const { return !(*this == value); }
  219. bool operator!=(const wxUniCharRef& value) const { return !(*this == value); }
  220. bool operator!=(char value) const { return !(*this == value); }
  221. bool operator!=(wchar_t value) const { return !(*this == value); }
  222. wxVariant& operator=(const wxUniChar& value);
  223. wxVariant& operator=(const wxUniCharRef& value) { return *this = wxUniChar(value); }
  224. wxVariant& operator=(char value) { return *this = wxUniChar(value); }
  225. wxVariant& operator=(wchar_t value) { return *this = wxUniChar(value); }
  226. operator wxUniChar() const { return GetChar(); }
  227. operator char() const { return GetChar(); }
  228. operator wchar_t() const { return GetChar(); }
  229. wxUniChar GetChar() const;
  230. // wxArrayString
  231. wxVariant(const wxArrayString& val, const wxString& name = wxEmptyString);
  232. bool operator== (const wxArrayString& value) const;
  233. bool operator!= (const wxArrayString& value) const;
  234. void operator= (const wxArrayString& value);
  235. operator wxArrayString () const { return GetArrayString(); }
  236. wxArrayString GetArrayString() const;
  237. // void*
  238. wxVariant(void* ptr, const wxString& name = wxEmptyString);
  239. bool operator== (void* value) const;
  240. bool operator!= (void* value) const;
  241. void operator= (void* value);
  242. operator void* () const { return GetVoidPtr(); }
  243. void* GetVoidPtr() const;
  244. // wxObject*
  245. wxVariant(wxObject* ptr, const wxString& name = wxEmptyString);
  246. bool operator== (wxObject* value) const;
  247. bool operator!= (wxObject* value) const;
  248. void operator= (wxObject* value);
  249. wxObject* GetWxObjectPtr() const;
  250. #if wxUSE_LONGLONG
  251. // wxLongLong
  252. wxVariant(wxLongLong, const wxString& name = wxEmptyString);
  253. bool operator==(wxLongLong value) const;
  254. bool operator!=(wxLongLong value) const;
  255. void operator=(wxLongLong value);
  256. operator wxLongLong() const { return GetLongLong(); }
  257. wxLongLong GetLongLong() const;
  258. // wxULongLong
  259. wxVariant(wxULongLong, const wxString& name = wxEmptyString);
  260. bool operator==(wxULongLong value) const;
  261. bool operator!=(wxULongLong value) const;
  262. void operator=(wxULongLong value);
  263. operator wxULongLong() const { return GetULongLong(); }
  264. wxULongLong GetULongLong() const;
  265. #endif
  266. // ------------------------------
  267. // list operations
  268. // ------------------------------
  269. wxVariant(const wxVariantList& val, const wxString& name = wxEmptyString); // List of variants
  270. bool operator== (const wxVariantList& value) const;
  271. bool operator!= (const wxVariantList& value) const;
  272. void operator= (const wxVariantList& value) ;
  273. // Treat a list variant as an array
  274. wxVariant operator[] (size_t idx) const;
  275. wxVariant& operator[] (size_t idx) ;
  276. wxVariantList& GetList() const ;
  277. // Return the number of elements in a list
  278. size_t GetCount() const;
  279. // Make empty list
  280. void NullList();
  281. // Append to list
  282. void Append(const wxVariant& value);
  283. // Insert at front of list
  284. void Insert(const wxVariant& value);
  285. // Returns true if the variant is a member of the list
  286. bool Member(const wxVariant& value) const;
  287. // Deletes the nth element of the list
  288. bool Delete(size_t item);
  289. // Clear list
  290. void ClearList();
  291. public:
  292. // Type conversion
  293. bool Convert(long* value) const;
  294. bool Convert(bool* value) const;
  295. bool Convert(double* value) const;
  296. bool Convert(wxString* value) const;
  297. bool Convert(wxUniChar* value) const;
  298. bool Convert(char* value) const;
  299. bool Convert(wchar_t* value) const;
  300. #if wxUSE_DATETIME
  301. bool Convert(wxDateTime* value) const;
  302. #endif // wxUSE_DATETIME
  303. #if wxUSE_LONGLONG
  304. bool Convert(wxLongLong* value) const;
  305. bool Convert(wxULongLong* value) const;
  306. #ifdef wxLongLong_t
  307. bool Convert(wxLongLong_t* value) const
  308. {
  309. wxLongLong temp;
  310. if ( !Convert(&temp) )
  311. return false;
  312. *value = temp.GetValue();
  313. return true;
  314. }
  315. bool Convert(wxULongLong_t* value) const
  316. {
  317. wxULongLong temp;
  318. if ( !Convert(&temp) )
  319. return false;
  320. *value = temp.GetValue();
  321. return true;
  322. }
  323. #endif // wxLongLong_t
  324. #endif // wxUSE_LONGLONG
  325. // Attributes
  326. protected:
  327. virtual wxObjectRefData *CreateRefData() const;
  328. virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const;
  329. wxString m_name;
  330. private:
  331. DECLARE_DYNAMIC_CLASS(wxVariant)
  332. };
  333. //
  334. // wxVariant <-> wxAny conversion code
  335. //
  336. #if wxUSE_ANY
  337. #include "wx/any.h"
  338. // In order to convert wxAny to wxVariant, we need to be able to associate
  339. // wxAnyValueType with a wxVariantData factory function.
  340. typedef wxVariantData* (*wxVariantDataFactory)(const wxAny& any);
  341. // Actual Any-to-Variant registration must be postponed to a time when all
  342. // global variables have been initialized. Hence this arrangement.
  343. // wxAnyToVariantRegistration instances are kept in global scope and
  344. // wxAnyValueTypeGlobals in any.cpp will use their data when the time is
  345. // right.
  346. class WXDLLIMPEXP_BASE wxAnyToVariantRegistration
  347. {
  348. public:
  349. wxAnyToVariantRegistration(wxVariantDataFactory factory);
  350. virtual ~wxAnyToVariantRegistration();
  351. virtual wxAnyValueType* GetAssociatedType() = 0;
  352. wxVariantDataFactory GetFactory() const { return m_factory; }
  353. private:
  354. wxVariantDataFactory m_factory;
  355. };
  356. template<typename T>
  357. class wxAnyToVariantRegistrationImpl : public wxAnyToVariantRegistration
  358. {
  359. public:
  360. wxAnyToVariantRegistrationImpl(wxVariantDataFactory factory)
  361. : wxAnyToVariantRegistration(factory)
  362. {
  363. }
  364. virtual wxAnyValueType* GetAssociatedType()
  365. {
  366. return wxAnyValueTypeImpl<T>::GetInstance();
  367. }
  368. private:
  369. };
  370. #define DECLARE_WXANY_CONVERSION() \
  371. virtual bool GetAsAny(wxAny* any) const; \
  372. static wxVariantData* VariantDataFactory(const wxAny& any);
  373. #define _REGISTER_WXANY_CONVERSION(T, CLASSNAME, FUNC) \
  374. static wxAnyToVariantRegistrationImpl<T> \
  375. gs_##CLASSNAME##AnyToVariantRegistration = \
  376. wxAnyToVariantRegistrationImpl<T>(&FUNC);
  377. #define REGISTER_WXANY_CONVERSION(T, CLASSNAME) \
  378. _REGISTER_WXANY_CONVERSION(T, CLASSNAME, CLASSNAME::VariantDataFactory)
  379. #define IMPLEMENT_TRIVIAL_WXANY_CONVERSION(T, CLASSNAME) \
  380. bool CLASSNAME::GetAsAny(wxAny* any) const \
  381. { \
  382. *any = m_value; \
  383. return true; \
  384. } \
  385. wxVariantData* CLASSNAME::VariantDataFactory(const wxAny& any) \
  386. { \
  387. return new CLASSNAME(wxANY_AS(any, T)); \
  388. } \
  389. REGISTER_WXANY_CONVERSION(T, CLASSNAME)
  390. #else // if !wxUSE_ANY
  391. #define DECLARE_WXANY_CONVERSION()
  392. #define REGISTER_WXANY_CONVERSION(T, CLASSNAME)
  393. #define IMPLEMENT_TRIVIAL_WXANY_CONVERSION(T, CLASSNAME)
  394. #endif // wxUSE_ANY/!wxUSE_ANY
  395. #define DECLARE_VARIANT_OBJECT(classname) \
  396. DECLARE_VARIANT_OBJECT_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE)
  397. #define DECLARE_VARIANT_OBJECT_EXPORTED(classname,expdecl) \
  398. expdecl classname& operator << ( classname &object, const wxVariant &variant ); \
  399. expdecl wxVariant& operator << ( wxVariant &variant, const classname &object );
  400. #define IMPLEMENT_VARIANT_OBJECT(classname) \
  401. IMPLEMENT_VARIANT_OBJECT_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE)
  402. #define IMPLEMENT_VARIANT_OBJECT_EXPORTED_NO_EQ(classname,expdecl) \
  403. class classname##VariantData: public wxVariantData \
  404. { \
  405. public:\
  406. classname##VariantData() {} \
  407. classname##VariantData( const classname &value ) { m_value = value; } \
  408. \
  409. classname &GetValue() { return m_value; } \
  410. \
  411. virtual bool Eq(wxVariantData& data) const; \
  412. \
  413. virtual wxString GetType() const; \
  414. virtual wxClassInfo* GetValueClassInfo(); \
  415. \
  416. virtual wxVariantData* Clone() const { return new classname##VariantData(m_value); } \
  417. \
  418. DECLARE_WXANY_CONVERSION() \
  419. protected:\
  420. classname m_value; \
  421. };\
  422. \
  423. wxString classname##VariantData::GetType() const\
  424. {\
  425. return m_value.GetClassInfo()->GetClassName();\
  426. }\
  427. \
  428. wxClassInfo* classname##VariantData::GetValueClassInfo()\
  429. {\
  430. return m_value.GetClassInfo();\
  431. }\
  432. \
  433. expdecl classname& operator << ( classname &value, const wxVariant &variant )\
  434. {\
  435. wxASSERT( variant.GetType() == #classname );\
  436. \
  437. classname##VariantData *data = (classname##VariantData*) variant.GetData();\
  438. value = data->GetValue();\
  439. return value;\
  440. }\
  441. \
  442. expdecl wxVariant& operator << ( wxVariant &variant, const classname &value )\
  443. {\
  444. classname##VariantData *data = new classname##VariantData( value );\
  445. variant.SetData( data );\
  446. return variant;\
  447. } \
  448. IMPLEMENT_TRIVIAL_WXANY_CONVERSION(classname, classname##VariantData)
  449. // implements a wxVariantData-derived class using for the Eq() method the
  450. // operator== which must have been provided by "classname"
  451. #define IMPLEMENT_VARIANT_OBJECT_EXPORTED(classname,expdecl) \
  452. IMPLEMENT_VARIANT_OBJECT_EXPORTED_NO_EQ(classname,wxEMPTY_PARAMETER_VALUE expdecl) \
  453. \
  454. bool classname##VariantData::Eq(wxVariantData& data) const \
  455. {\
  456. wxASSERT( GetType() == data.GetType() );\
  457. \
  458. classname##VariantData & otherData = (classname##VariantData &) data;\
  459. \
  460. return otherData.m_value == m_value;\
  461. }\
  462. // implements a wxVariantData-derived class using for the Eq() method a shallow
  463. // comparison (through wxObject::IsSameAs function)
  464. #define IMPLEMENT_VARIANT_OBJECT_SHALLOWCMP(classname) \
  465. IMPLEMENT_VARIANT_OBJECT_EXPORTED_SHALLOWCMP(classname, wxEMPTY_PARAMETER_VALUE)
  466. #define IMPLEMENT_VARIANT_OBJECT_EXPORTED_SHALLOWCMP(classname,expdecl) \
  467. IMPLEMENT_VARIANT_OBJECT_EXPORTED_NO_EQ(classname,wxEMPTY_PARAMETER_VALUE expdecl) \
  468. \
  469. bool classname##VariantData::Eq(wxVariantData& data) const \
  470. {\
  471. wxASSERT( GetType() == data.GetType() );\
  472. \
  473. classname##VariantData & otherData = (classname##VariantData &) data;\
  474. \
  475. return (otherData.m_value.IsSameAs(m_value));\
  476. }\
  477. // Since we want type safety wxVariant we need to fetch and dynamic_cast
  478. // in a seemingly safe way so the compiler can check, so we define
  479. // a dynamic_cast /wxDynamicCast analogue.
  480. #define wxGetVariantCast(var,classname) \
  481. ((classname*)(var.IsValueKindOf(&classname::ms_classInfo) ?\
  482. var.GetWxObjectPtr() : NULL));
  483. // Replacement for using wxDynamicCast on a wxVariantData object
  484. #ifndef wxNO_RTTI
  485. #define wxDynamicCastVariantData(data, classname) dynamic_cast<classname*>(data)
  486. #endif
  487. #define wxStaticCastVariantData(data, classname) static_cast<classname*>(data)
  488. extern wxVariant WXDLLIMPEXP_BASE wxNullVariant;
  489. #endif // wxUSE_VARIANT
  490. #endif // _WX_VARIANT_H_