any.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: any.h
  3. // Purpose: interface of wxAny
  4. // Author: wxWidgets team
  5. // Licence: wxWindows licence
  6. /////////////////////////////////////////////////////////////////////////////
  7. /**
  8. @class wxAny
  9. The wxAny class represents a container for any type. Its value
  10. can be changed at run time, possibly to a different type of value.
  11. wxAny is a backwards-incompatible (but convertible) successor class for
  12. wxVariant, essentially doing the same thing in a more modern, template-
  13. based manner and with transparent support for any user data type.
  14. Some pseudo-code'ish example of use with arbitrary user data:
  15. @code
  16. void SomeFunction()
  17. {
  18. MyClass myObject;
  19. wxAny any = myObject;
  20. // Do something
  21. // ...
  22. // Let's do a sanity check to make sure that any still holds
  23. // data of correct type.
  24. if ( any.CheckType<MyClass>() )
  25. {
  26. // Thank goodness, still a correct type.
  27. MyClass myObject2 = any.As<MyClass>();
  28. }
  29. else
  30. {
  31. // Something has gone horribly wrong!
  32. wxFAIL();
  33. }
  34. }
  35. @endcode
  36. When compared to wxVariant, there are various internal implementation
  37. differences as well. For instance, wxAny only allocates separate data
  38. object in heap for large objects (i.e. ones with size more than
  39. WX_ANY_VALUE_BUFFER_SIZE, which at the time of writing is 16 bytes).
  40. @note When performing conversions between strings and floating point
  41. numbers, the representation of numbers in C locale is always used.
  42. I.e. @code wxAny("1.23").GetAs<double>() @endcode will always work,
  43. even if the current locale uses comma as decimal separator.
  44. @library{wxbase}
  45. @category{data}
  46. @see wxAnyValueType, wxVariant, @ref overview_cpp_rtti_disabled
  47. */
  48. class wxAny
  49. {
  50. public:
  51. /**
  52. Default constructor. It seeds the object with a null value.
  53. */
  54. wxAny();
  55. /**
  56. Constructs wxAny from data.
  57. */
  58. template<typename T>
  59. wxAny(const T& value);
  60. /**
  61. Constructs wxAny from another wxAny.
  62. */
  63. wxAny(const wxAny& any);
  64. /**
  65. Constructs wxAny, converting value from wxVariant.
  66. @remarks Because of this conversion, it is not usually possible to
  67. have wxAny that actually holds a wxVariant. If wxVariant
  68. cannot be converted to a specific data type, wxAny will then
  69. hold and manage reference to wxVariantData* similar to how
  70. wxVariant does.
  71. */
  72. wxAny(const wxVariant& variant);
  73. /**
  74. Destructor.
  75. */
  76. ~wxAny();
  77. /**
  78. This template function converts wxAny into given type. In most cases
  79. no type conversion is performed, so if the type is incorrect an
  80. assertion failure will occur.
  81. @remarks For conveniency, conversion is done when T is wxString. This
  82. is useful when a string literal (which are treated as
  83. const char* and const wchar_t*) has been assigned to wxAny.
  84. This template function may not work properly with Visual C++
  85. 6. For full compiler compatibility, please use
  86. wxANY_AS(any, T) macro instead.
  87. */
  88. template<typename T>
  89. T As() const;
  90. /**
  91. Use this template function for checking if this wxAny holds
  92. a specific C++ data type.
  93. @remarks This template function may not work properly with Visual C++
  94. 6. For full compiler compatibility, please use
  95. wxANY_CHECK_TYPE(any, T) macro instead.
  96. @see wxAnyValueType::CheckType()
  97. */
  98. template<typename T>
  99. bool CheckType() const;
  100. /**
  101. Template function that retrieves and converts the value of this
  102. wxAny to the type that T* value is.
  103. @return Returns @true if conversion was successful.
  104. */
  105. template<typename T>
  106. bool GetAs(T* value) const;
  107. /**
  108. Specialization of GetAs() that allows conversion of wxAny into
  109. wxVariant.
  110. @return Returns @true if conversion was successful. Conversion usually
  111. only fails if variant used custom wxVariantData that did not
  112. implement the wxAny to wxVariant conversion functions.
  113. */
  114. bool GetAs(wxVariant* value) const;
  115. /**
  116. Returns the value type as wxAnyValueType instance.
  117. @remarks You cannot reliably test whether two wxAnys are of
  118. same value type by simply comparing return values
  119. of wxAny::GetType(). Instead, use wxAny::HasSameType().
  120. @see HasSameType()
  121. */
  122. const wxAnyValueType* GetType() const;
  123. /**
  124. Returns @true if this and another wxAny have the same
  125. value type.
  126. */
  127. bool HasSameType(const wxAny& other) const;
  128. /**
  129. Tests if wxAny is null (that is, whether there is no data).
  130. */
  131. bool IsNull() const;
  132. /**
  133. Makes wxAny null (that is, clears it).
  134. */
  135. void MakeNull();
  136. //@{
  137. /**
  138. @name Assignment operators
  139. */
  140. template<typename T>
  141. wxAny& operator=(const T &value);
  142. wxAny& operator=(const wxAny &any);
  143. wxAny& operator=(const wxVariant &variant);
  144. //@}
  145. //@{
  146. /**
  147. @name Equality operators
  148. @remarks Generic template-based comparison operators have not been
  149. provided for various code consistency reasons, so for custom
  150. data types you have do something like this:
  151. @code
  152. if ( any.CheckType<MyClass*>() &&
  153. any.As<MyClass*>() == myObjectPtr )
  154. {
  155. // Do something if any stores myObjectPtr
  156. }
  157. @endcode
  158. */
  159. bool operator==(signed char value) const;
  160. bool operator==(signed short value) const;
  161. bool operator==(signed int value) const;
  162. bool operator==(signed long value) const;
  163. bool operator==(wxLongLong_t value) const;
  164. bool operator==(unsigned char value) const;
  165. bool operator==(unsigned short value) const;
  166. bool operator==(unsigned int value) const;
  167. bool operator==(unsigned long value) const;
  168. bool operator==(wxULongLong_t value) const;
  169. bool operator==(float value) const;
  170. bool operator==(double value) const;
  171. bool operator==(bool value) const;
  172. bool operator==(const char* value) const;
  173. bool operator==(const wchar_t* value) const;
  174. bool operator==(const wxString& value) const;
  175. //@}
  176. //@{
  177. /**
  178. @name Inequality operators
  179. */
  180. bool operator!=(signed char value) const;
  181. bool operator!=(signed short value) const;
  182. bool operator!=(signed int value) const;
  183. bool operator!=(signed long value) const;
  184. bool operator!=(wxLongLong_t value) const;
  185. bool operator!=(unsigned char value) const;
  186. bool operator!=(unsigned short value) const;
  187. bool operator!=(unsigned int value) const;
  188. bool operator!=(unsigned long value) const;
  189. bool operator!=(wxULongLong_t value) const;
  190. bool operator!=(float value) const;
  191. bool operator!=(double value) const;
  192. bool operator!=(bool value) const;
  193. bool operator!=(const char* value) const;
  194. bool operator!=(const wchar_t* value) const;
  195. bool operator!=(const wxString& value) const;
  196. //@}
  197. };
  198. /**
  199. This is value getter macro that is more compatible with older
  200. compilers, such as Visual C++ 6.0.
  201. */
  202. #define wxANY_AS(any, T)
  203. /**
  204. This is type checking macro that is more compatible with older
  205. compilers, such as Visual C++ 6.0.
  206. */
  207. #define wxANY_CHECK_TYPE(any, T)
  208. /**
  209. Size of the wxAny value buffer.
  210. */
  211. enum
  212. {
  213. WX_ANY_VALUE_BUFFER_SIZE = 16
  214. };
  215. /**
  216. Type for buffer within wxAny for holding data.
  217. */
  218. union wxAnyValueBuffer
  219. {
  220. void* m_ptr;
  221. wxByte m_buffer[WX_ANY_VALUE_BUFFER_SIZE];
  222. };
  223. /**
  224. @class wxAnyValueType
  225. wxAnyValueType is base class for value type functionality for C++ data
  226. types used with wxAny. Usually the default template will create a
  227. satisfactory wxAnyValueType implementation for a data type, but
  228. sometimes you may need to add some customization. To do this you will need
  229. to add specialized template of wxAnyValueTypeImpl<>. Often your only
  230. need may be to add dynamic type conversion which would be done like
  231. this:
  232. @code
  233. template<>
  234. class wxAnyValueTypeImpl<MyClass> :
  235. public wxAnyValueTypeImplBase<MyClass>
  236. {
  237. WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
  238. public:
  239. wxAnyValueTypeImpl() :
  240. wxAnyValueTypeImplBase<MyClass>() { }
  241. virtual ~wxAnyValueTypeImpl() { }
  242. virtual bool ConvertValue(const wxAnyValueBuffer& src,
  243. wxAnyValueType* dstType,
  244. wxAnyValueBuffer& dst) const
  245. {
  246. // GetValue() is a static member function implemented
  247. // in wxAnyValueTypeImplBase<>.
  248. MyClass value = GetValue(src);
  249. // TODO: Convert value from src buffer to destination
  250. // type and buffer. If cannot be done, return
  251. // false. This is a simple sample.
  252. if ( dstType->CheckType<wxString>() )
  253. {
  254. wxString s = value.ToString();
  255. wxAnyValueTypeImpl<wxString>::SetValue(s, dst);
  256. }
  257. else
  258. {
  259. return false;
  260. }
  261. }
  262. };
  263. //
  264. // Following must be placed somewhere in your source code
  265. WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
  266. @endcode
  267. wxAnyValueTypeImplBase<> template, from which we inherit in the above
  268. example, contains the bulk of the default wxAnyValueTypeImpl<> template
  269. implementation, and as such allows you to easily add some minor
  270. customization.
  271. If you need a have complete control over the type interpretation, you
  272. will need to derive a class directly from wxAnyValueType, like this:
  273. @code
  274. template <>
  275. class wxAnyValueTypeImpl<MyClass> : public wxAnyValueType
  276. {
  277. WX_DECLARE_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
  278. public:
  279. virtual void DeleteValue(wxAnyValueBuffer& buf) const
  280. {
  281. // TODO: Free the data in buffer
  282. // It is important to clear the buffer like this
  283. // at the end of DeleteValue().
  284. buf.m_ptr = NULL;
  285. }
  286. virtual void CopyBuffer(const wxAnyValueBuffer& src,
  287. wxAnyValueBuffer& dst) const
  288. {
  289. // TODO: Copy value from one buffer to another.
  290. // dst is already uninitialized and does not
  291. // need to be freed.
  292. }
  293. virtual bool ConvertValue(const wxAnyValueBuffer& src,
  294. wxAnyValueType* dstType,
  295. wxAnyValueBuffer& dst) const
  296. {
  297. // TODO: Convert value from src buffer to destination
  298. // type and buffer.
  299. }
  300. //
  301. // Following static functions must be implemented
  302. //
  303. static void SetValue(const T& value,
  304. wxAnyValueBuffer& buf)
  305. {
  306. // TODO: Store value into buf.
  307. }
  308. static const T& GetValue(const wxAnyValueBuffer& buf)
  309. {
  310. // TODO: Return reference to value stored in buffer.
  311. }
  312. };
  313. //
  314. // Following must be placed somewhere in your source code
  315. WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
  316. @endcode
  317. @library{wxbase}
  318. @category{data}
  319. @see wxAny
  320. */
  321. class wxAnyValueType
  322. {
  323. public:
  324. /**
  325. Default constructor.
  326. */
  327. wxAnyValueType();
  328. /**
  329. Destructor.
  330. */
  331. virtual ~wxAnyValueType();
  332. /**
  333. Use this template function for checking if wxAnyValueType represents
  334. a specific C++ data type.
  335. @remarks This template function does not work on some older compilers
  336. (such as Visual C++ 6.0). For full compiler compatibility
  337. please use wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T) macro
  338. instead.
  339. @see wxAny::CheckType()
  340. */
  341. template <typename T>
  342. bool CheckType() const;
  343. /**
  344. Convert value into buffer of different type. Return false if
  345. not possible.
  346. */
  347. virtual bool ConvertValue(const wxAnyValueBuffer& src,
  348. wxAnyValueType* dstType,
  349. wxAnyValueBuffer& dst) const = 0;
  350. /**
  351. Implement this for buffer-to-buffer copy.
  352. @param src
  353. This is the source data buffer.
  354. @param dst
  355. This is the destination data buffer that is in either
  356. uninitialized or freed state.
  357. */
  358. virtual void CopyBuffer(const wxAnyValueBuffer& src,
  359. wxAnyValueBuffer& dst) const = 0;
  360. /**
  361. This function is called every time the data in wxAny
  362. buffer needs to be freed.
  363. */
  364. virtual void DeleteValue(wxAnyValueBuffer& buf) const = 0;
  365. /**
  366. This function is used for internal type matching.
  367. */
  368. virtual bool IsSameType(const wxAnyValueType* otherType) const = 0;
  369. };
  370. /**
  371. This is type checking macro that is more compatible with older
  372. compilers, such as Visual C++ 6.0.
  373. */
  374. #define wxANY_VALUE_TYPE_CHECK_TYPE(valueTypePtr, T)