variant.h 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159
  1. /************************************************************************************
  2. * *
  3. * Copyright (c) 2014 - 2018 Axel Menzel <info@rttr.org> *
  4. * *
  5. * This file is part of RTTR (Run Time Type Reflection) *
  6. * License: MIT License *
  7. * *
  8. * Permission is hereby granted, free of charge, to any person obtaining *
  9. * a copy of this software and associated documentation files (the "Software"), *
  10. * to deal in the Software without restriction, including without limitation *
  11. * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  12. * and/or sell copies of the Software, and to permit persons to whom the *
  13. * Software is furnished to do so, subject to the following conditions: *
  14. * *
  15. * The above copyright notice and this permission notice shall be included in *
  16. * all copies or substantial portions of the Software. *
  17. * *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
  24. * SOFTWARE. *
  25. * *
  26. *************************************************************************************/
  27. #ifndef RTTR_VARIANT_H_
  28. #define RTTR_VARIANT_H_
  29. #include "rttr/detail/base/core_prerequisites.h"
  30. #include "rttr/detail/misc/misc_type_traits.h"
  31. #include "rttr/detail/variant/variant_data.h"
  32. #include "rttr/detail/misc/argument_wrapper.h"
  33. #include "rttr/detail/variant/variant_compare.h"
  34. #include <type_traits>
  35. #include <cstddef>
  36. #include <cstdint>
  37. #include <algorithm>
  38. #include <string>
  39. namespace rttr
  40. {
  41. class variant_associative_view;
  42. class variant_sequential_view;
  43. class type;
  44. class variant;
  45. class argument;
  46. class instance;
  47. namespace detail
  48. {
  49. template<class T>
  50. RTTR_INLINE T* unsafe_variant_cast(variant* operand) RTTR_NOEXCEPT;
  51. template<class T>
  52. RTTR_INLINE const T* unsafe_variant_cast(const variant* operand) RTTR_NOEXCEPT;
  53. struct data_address_container;
  54. template<typename T>
  55. struct empty_type_converter;
  56. template<typename T, typename Tp, typename Converter = empty_type_converter<T>>
  57. struct variant_data_base_policy;
  58. struct variant_data_policy_nullptr_t;
  59. enum class variant_policy_operation : uint8_t;
  60. template<typename T, typename Decayed = decay_except_array_t<T>>
  61. using decay_variant_t = enable_if_t<!std::is_same<Decayed, variant>::value, Decayed>;
  62. using variant_policy_func = bool (*)(variant_policy_operation, const variant_data&, argument_wrapper);
  63. }
  64. /*!
  65. * The \ref variant class allows to store data of any type and convert between these types transparently.
  66. *
  67. * This class serves as container for any given single \ref get_type() "type". It can hold one value at a time
  68. * (using containers you can hold multiple types e.g. `std::vector<int>`). Remark that the content is copied
  69. * into the variant class. Even raw arrays (e.g. `int[10]`) are copied. However, the internal implementation of variant
  70. * has an optimization for storing small types, which avoid heap allocation.
  71. *
  72. * The main purpose of this class is to be the return value for \ref property::get_value() "property" and
  73. * \ref method::invoke() "method" invokes or as container for storing meta data.
  74. *
  75. * Copying and Assignment
  76. * ----------------------
  77. * A \ref variant object can be copied and assigned, however each copy will perform a copy of the contained value.
  78. *
  79. * Typical Usage
  80. * -------------
  81. *
  82. * \code{.cpp}
  83. * variant var;
  84. * var = 23; // copy integer
  85. * int x = var.to_int(); // x = 23
  86. *
  87. * var = "Hello World"; // var contains now a std::string (implicit conversion of string literals to std::string)
  88. * int y = var.to_int(); // y = 0, because invalid conversion
  89. *
  90. * var = "42"; // contains a std::string
  91. * std::cout << var.to_int(); // convert std::string to integer and prints "42"
  92. *
  93. * int my_array[100];
  94. * var = my_array; // copies the content of my_array into var
  95. * auto& arr = var.get_value<int[100]>(); // extracts the content of var by reference
  96. * \endcode
  97. *
  98. * Extract Value
  99. * -------------
  100. * For extracting a value out of a variant you can use the \ref get_value() function.
  101. * This will return a *const reference* to the contained value.
  102. * However, you must instantiated this function with the exact type of the stored value,
  103. * otherwise undefined behaviour will occur.
  104. * Therefore you **should** check it's \ref get_type() "type" before extracting with \ref is_type<T>().
  105. *
  106. * See following example:
  107. * \code{.cpp}
  108. * struct custom_type
  109. * {
  110. * //...
  111. * };
  112. *
  113. * variant var = custom_type{};
  114. * if (var.is_type<custom_type>()) // yields to true
  115. * const custom_type& value = var.get_value<custom_type>(); // extracts the value by reference
  116. * \endcode
  117. *
  118. * Conversion
  119. * ----------
  120. * The \ref variant class offers three possibilities to convert to a new type.
  121. * - \ref convert(const type& target_type) "convert(const type& target_type)" - convert the variant internally to a new type
  122. * - \ref variant::convert(bool* ok) "convert\<T\>(bool *ok)" - convert the contained value to an internally default created value of type \p T and returns this new value
  123. * - \ref variant::convert(T& value) "convert\<T\>(T& value)" - convert the contained value to a given \p value of type \p T
  124. *
  125. * See following example code:
  126. * \code{.cpp}
  127. * variant var = 23; // var contains an int
  128. * if(var.can_convert<std::string>()) // check whether conversion is possible
  129. * {
  130. * var.convert(type::get<std::string>()); // var contains now a std::string, with value => "23"
  131. * var.is_type<std::string>(); // yields to 'true'
  132. * }
  133. *
  134. * bool ok = false;
  135. * int int_value = var.convert<int>(&ok); // int_value == 23, ok yields to 'true'
  136. * // or
  137. * uint8_t small_int = 0;
  138. * bool result = var.convert<uint8_t>(small_int); // result == false, because small_int cannot hold the value '500'
  139. *
  140. * \endcode
  141. *
  142. * \remark
  143. * It is possible that \ref can_convert() will return `true`, but \ref convert() will actually fail and return `false`.
  144. * The reason for this is \ref can_convert() will return the general ability of converting between types given suitable data;
  145. * when no suitable data is given, the conversion cannot be performed.
  146. *
  147. * A good example is the conversion from `std::string` to `int`.
  148. * \code{.cpp}
  149. * variant var = "Answer: 42";
  150. * var.can_convert<int>(); // yields to 'true'
  151. * int number;
  152. * bool result = var.convert(number); // yields to 'false', because the string contains non-numeric characters
  153. *
  154. * \endcode
  155. *
  156. * Hence, it is important to have both functions return true for a successful conversion.
  157. *
  158. * Custom Converter
  159. * ----------------
  160. * The variant class allows to convert from and to user-defined types,
  161. * therefore you have to register a conversion function.
  162. *
  163. * See following example code:
  164. * \code{.cpp}
  165. * std::string converter_func(const custom_type& value, bool& ok)
  166. * {
  167. * ok = true;
  168. * // convert value to std::string
  169. * return std::string(...);
  170. * }
  171. *
  172. * //...
  173. * variant var = custom_type(...);
  174. * var.can_convert<std::string>(); // return 'false'
  175. * // register the conversion function
  176. * type::register_converter_func(converter_func);
  177. *
  178. * var.can_convert<std::string>(); // return 'true'
  179. * var.to_string(); // converts from 'custom_type' to 'std::string'
  180. * \endcode
  181. *
  182. * For more information see \ref type::register_converter_func()
  183. *
  184. * \see variant_array_view
  185. */
  186. class RTTR_API variant
  187. {
  188. public:
  189. /*!
  190. * \brief Constructs an invalid variant. That means a valid which contains no data.
  191. *
  192. * \see is_valid()
  193. */
  194. RTTR_INLINE variant();
  195. /*!
  196. * \brief Constructs a new variant with the new value \p val.
  197. * The value will be copied or moved into the variant.
  198. */
  199. template<typename T, typename Tp = detail::decay_variant_t<T>>
  200. variant(T&& val);
  201. /*!
  202. * \brief Constructs a new variant object from the given variant \p other.
  203. */
  204. variant(const variant& other);
  205. /*!
  206. * \brief Constructs a new variant via move constructor.
  207. */
  208. variant(variant&& other);
  209. /*!
  210. * \brief Destroys the variant and the contained object.
  211. */
  212. RTTR_INLINE ~variant();
  213. /*!
  214. * Assigns the value of the \p other object to this variant.
  215. *
  216. * \return A reference to the variant with the new data.
  217. */
  218. template<typename T, typename Tp = detail::decay_variant_t<T>>
  219. variant& operator=(T&& other);
  220. /*!
  221. * \brief Assigns the value of the \a other variant to this variant.
  222. *
  223. * \return A reference to the variant with the new data.
  224. */
  225. variant& operator=(variant&& other);
  226. /*!
  227. * \brief Assigns the value of the \a other variant to this variant.
  228. *
  229. * \return A reference to the variant with the new data.
  230. */
  231. variant& operator=(const variant& other);
  232. /*!
  233. * \brief Compares this variant with \p other and returns `true` if they are equal; otherwise returns `false`.
  234. *
  235. * The variant uses the equality operator of the containing \ref get_type() "type" to check for equality.
  236. * When \p other is not of the same type as the containing type, it will try to convert to it and do then the equality check.
  237. *
  238. * \remark In order to use this function with template types, like `std::tuple<int, std::string>`,
  239. * you need to register the comparison operator to the type system with \ref type::register_comparators<T>().
  240. * The reason for that is, template types might define the `==` operator, but not the contained template type.
  241. *
  242. * \note Comparability might not be available for the type stored in this variant or in \p other.
  243. *
  244. * \see \ref variant::operator!=(const variant&) const "operator!="
  245. *
  246. * \return A boolean with value `true`, that indicates both variant's are equal, otherwise `false`.
  247. */
  248. RTTR_INLINE bool operator==(const variant& other) const;
  249. /*!
  250. * \brief Compares this variant with \p other and returns `true` if they are **not** equal; otherwise returns `false`.
  251. *
  252. * \remark In order to use this function with template types, like `std::tuple<int, std::string>`,
  253. * you need to register the comparison operator to the type system with \ref type::register_comparators<T>().
  254. * The reason for that is, template types might define the `!=` operator, but not the contained template type.
  255. *
  256. * \note Comparability might not be available for the type stored in this variant or in \p other.
  257. *
  258. * \see \ref variant::operator==(const variant&) const "operator=="
  259. *
  260. * \return A boolean with value `true`, that indicates both variant's are **not** equal, otherwise `false`.
  261. */
  262. RTTR_INLINE bool operator!=(const variant& other) const;
  263. /*!
  264. * \brief Compares this variant with \p other and returns `true` if this is *less than* \p other, otherwise returns `false`.
  265. *
  266. * The variant uses the *less than* operator of the containing \ref get_type() "type".
  267. * When \p other is not of the same type as the containing type, it will try to convert to it and do then the *less than* check.
  268. *
  269. * \remark In order to use this function with template types, like `std::tuple<int, std::string>`,
  270. * you need to register the comparison operator to the type system with \ref type::register_comparators<T>().
  271. * The reason for that is, template types might define the `<` operator, but not the contained template type.
  272. *
  273. * \note Comparability might not be available for the type stored in this variant or in \p other.
  274. *
  275. * \see \ref variant::operator>(const variant&) const "operator\>"
  276. *
  277. * \return A boolean with value `true`, that indicates that this variant is *less than* \p other, otherwise `false`.
  278. */
  279. RTTR_INLINE bool operator<(const variant& other) const;
  280. /*!
  281. * \brief Compares this variant with \p other and returns `true` if this is *less* or *equal* than \p other, otherwise returns `false`.
  282. *
  283. * The variant uses the *less than* and equality operator of the containing \ref get_type() "type"
  284. * to get the result of the comparision.
  285. *
  286. * \note Comparability might not be available for the type stored in this variant or in \p other.
  287. *
  288. * \see \ref variant::operator<(const variant&) const "operator\<",
  289. * \ref variant::operator==(const variant&) const "operator\=="
  290. *
  291. * \return A boolean with value `true`, that indicates that this variant is *less* or *equal* than \p other, otherwise `false`.
  292. */
  293. RTTR_INLINE bool operator<=(const variant& other) const;
  294. /*!
  295. * \brief Compares this variant with \p other and returns `true` if this is *greater* or *equal* then \p other, otherwise returns `false`.
  296. *
  297. * The variant uses the *greater than* and equality operator of the containing \ref get_type() "type"
  298. * to get the result of the comparision.
  299. *
  300. * \note Comparability might not be available for the type stored in this variant or in \p other.
  301. *
  302. * \see \ref variant::operator>(const variant&) const "operator\>",
  303. * \ref variant::operator==(const variant&) const "operator\=="
  304. *
  305. * \return A boolean with value `true`, that indicates that this variant is *greater* or *equal* than \p other, otherwise `false`.
  306. */
  307. RTTR_INLINE bool operator>=(const variant& other) const;
  308. /*!
  309. * \brief Compares this variant with \p other and returns `true` if this is *greater than* \p other, otherwise returns `false`.
  310. *
  311. * The variant uses the *less than* and equality operator of the containing \ref get_type() "type"
  312. * to get the result of the comparision.
  313. *
  314. * \note Comparability might not be available for the type stored in this variant or in \p other.
  315. *
  316. * \see \ref variant::operator<(const variant&) const "operator\<"
  317. *
  318. * \return A boolean with value `true`, that indicates that this variant is *greater than* \p other, otherwise `false`.
  319. */
  320. RTTR_INLINE bool operator>(const variant& other) const;
  321. /*!
  322. * \brief When the variant contains a value, then this function will clear the content.
  323. *
  324. * \remark After calling this function \ref is_valid() will return `false`.
  325. */
  326. void clear();
  327. /*!
  328. * \brief Swaps the content of this variant with \p other variant.
  329. */
  330. void swap(variant& other);
  331. /*!
  332. * \brief Returns `true` if the containing variant data is of the given template type `T`.
  333. *
  334. * \return True if variant data is of type `T`, otherwise false.
  335. */
  336. template<typename T>
  337. bool is_type() const;
  338. /*!
  339. * \brief Returns the \ref type object of underlying data.
  340. *
  341. * \remark When the variant has not stored any data, then an invalid \ref type object is returned.
  342. *
  343. * \return \ref type of the underlying data type.
  344. */
  345. type get_type() const;
  346. /*!
  347. * \brief Returns true if this variant is valid, that means the variant is holding some data.
  348. *
  349. * When the variant doesn't hold any data it will return false.
  350. *
  351. * \remark A variant can also hold `void` data, this is used to indicate that a method call,
  352. * which has no return value, was successfully. In this case, there is no data actually stored,
  353. * but this function will return true.
  354. *
  355. * \return `True` if this variant is valid, otherwise `false`.
  356. */
  357. bool is_valid() const;
  358. /*!
  359. * \brief Convenience function to check if this \ref variant is valid or not.
  360. *
  361. * \see is_valid()
  362. *
  363. * \return `True` if this \ref variant is valid, otherwise `false`.
  364. */
  365. explicit operator bool() const;
  366. /*!
  367. * \brief Returns true, when for the underlying or the \ref type::get_wrapped_type() "wrapped type"
  368. * an associative_mapper exists.
  369. *
  370. * \return True if the containing value is an associative container; otherwise false.
  371. */
  372. bool is_associative_container() const;
  373. /*!
  374. * \brief Returns true, when for the underlying or the \ref type::get_wrapped_type() "wrapped type"
  375. * an sequential_mapper exists.
  376. *
  377. * \return True if the containing value is an sequentail container; otherwise false.
  378. */
  379. bool is_sequential_container() const;
  380. /*!
  381. * \brief Returns a reference to the containing value as type \p T.
  382. *
  383. * \code{.cpp}
  384. * struct custom_type
  385. * {
  386. * //...
  387. * };
  388. *
  389. * variant var = custom_type{};
  390. * if (var.is_type<custom_type>()) // yields to true
  391. * custom_type& value = var.get_value<custom_type>(); // extracts the value by reference
  392. * \endcode
  393. *
  394. * \remark Only call this method when it is possible to return the containing value as the given type \p T.
  395. * Use therefore the method \ref is_type().
  396. * Otherwise the call leads to undefined behaviour.
  397. * Also make sure you don't clean this variant, when you still hold a reference to the containing value.
  398. *
  399. * \see is_type(), variant_cast<T>
  400. *
  401. * \return A reference to the stored value.
  402. */
  403. template<typename T>
  404. T& get_value();
  405. /*!
  406. * \brief Returns a reference to the containing value as type \p T.
  407. *
  408. * \code{.cpp}
  409. * struct custom_type
  410. * {
  411. * //...
  412. * };
  413. *
  414. * variant var = custom_type{};
  415. * if (var.is_type<custom_type>()) // yields to true
  416. * const custom_type& value = var.get_value<custom_type>(); // extracts the value by reference
  417. * \endcode
  418. *
  419. * \remark Only call this method when it is possible to return the containing value as the given type \p T.
  420. * Use therefore the method \ref is_type().
  421. * Otherwise the call leads to undefined behaviour.
  422. * Also make sure you don't clean this variant, when you still hold a reference to the containing value.
  423. *
  424. * \see is_type(), variant_cast<T>
  425. *
  426. * \return A reference to the stored value.
  427. */
  428. template<typename T>
  429. const T& get_value() const;
  430. /*!
  431. * \brief Returns a reference to the contained wrapped value as type \p T.
  432. *
  433. * \code{.cpp}
  434. * int value = 23;
  435. * variant var = std::ref(value);
  436. *
  437. * if (var.get_type().get_wrapped_type() == type::get<int>()) // yields to true
  438. * const int& ref_value = var.get_wrapped_value<int>(); // extracts the value by reference
  439. * \endcode
  440. *
  441. * \remark Only call this method when it is possible to return the containing value as the given type \p T.
  442. * Use therefore the method \ref rttr::type::get_wrapped_type() "get_wrapped_type()".
  443. * Otherwise the call leads to undefined behaviour.
  444. *
  445. * \see rttr::type::get_wrapped_type()
  446. *
  447. * \return A reference to the stored wrapped value.
  448. */
  449. template<typename T>
  450. const T& get_wrapped_value() const;
  451. /*!
  452. * \brief Extracts the wrapped value and copies its content into a new variant.
  453. *
  454. * \code{.cpp}
  455. * int value1 = 23;
  456. * variant var1 = std::ref(value1);
  457. *
  458. * if (var1.get_type().get_wrapped_type() == type::get<int>()) // yields to true
  459. * {
  460. * variant var2 = var1.extract_wrapped_value(); // value will be copied into "var2"
  461. * var2.get_type() == type::get<int>(); // yields to true
  462. * const int& value2 = var2.get_value<int>();
  463. * std::cout << value2 << std::endl; // prints "23"
  464. * }
  465. * \endcode
  466. *
  467. * \remark Calling this method works only for wrapped types which are copiable.
  468. * When you work with custom types, which are not copyable, the variant will be \ref is_valid "invalid"
  469. *
  470. * \return A variant with the wrapped value.
  471. *
  472. * \see type::is_wrapper()
  473. */
  474. variant extract_wrapped_value() const;
  475. /*!
  476. * \brief Returns `true` if the contained value can be converted to the given type \p T.
  477. * Otherwise `false`.
  478. *
  479. * \return `True` if this variant can be converted to `T`; otherwise `false`.
  480. *
  481. * \see convert(), type::register_converter_func()
  482. */
  483. template<typename T>
  484. bool can_convert() const;
  485. /*!
  486. * \brief Returns `true` if the contained value can be converted to the given type \p target_type;
  487. * otherwise `false`.
  488. *
  489. * The returned value indicates that a conversion is in general possible.
  490. * However a conversion might still fail when doing the actual conversion with \ref convert().
  491. * An example is the conversion from a string to a number.
  492. * When the string does not contain non-numeric characters, the conversion will not succeed.
  493. *
  494. * \return `True` if this variant can be converted to \p target_type; otherwise `false`.
  495. *
  496. * \see convert(), type::register_converter_func()
  497. */
  498. bool can_convert(const type& target_type) const;
  499. /*!
  500. * \brief Converts the containing variant internally to the given type \p target_type.
  501. * When the conversion was successfully the function will return `true`.
  502. * When the conversion fails, then the containing variant value stays the same and the function will return `false`.
  503. *
  504. * There are already certain standard type conversions implemented:
  505. * 1. Conversion of all arithmetic types (e.g. `double` to `int`, 'std::size_t' to 'int8_t' and so on)
  506. * 2. Conversion of all arithmetic types to and from `std::string`.
  507. * 3. Conversion of enum types to `std::string`, its underlying arithmetic types and vice versa.
  508. * 4. Conversion of \ref rttr::wrapper_mapper<T> "wrapper classes" to wrapped types and vice versa (e.g, `std::shared_ptr<int>` to `int*`)
  509. * 5. Conversion of raw pointers to its derived types, if a \ref rttr_cast to the type described by \p target_type would succeed.
  510. *
  511. * See therefore following example code:
  512. * \code{.cpp}
  513. * struct base { virtual ~base(){} RTTR_ENABLE() };
  514. * struct derived : base { RTTR_ENABLE(base) };
  515. * derived d;
  516. * variant var = static_cast<base*>(&d); // var contains a '*base' ptr
  517. * bool ret = var.convert(type::get<derived*>()); // yields to 'true'
  518. * var.is_type<derived*>(); // yields to 'true'
  519. * \endcode
  520. *
  521. * Additionally, it is possible to add custom conversion function, which has to be registered
  522. * via \ref type::register_converter_func().
  523. *
  524. * \return `True` if this variant can be converted to \p target_type; otherwise `false`.
  525. *
  526. * \see can_convert(), type::register_converter_func()
  527. */
  528. bool convert(const type& target_type);
  529. /*!
  530. * \brief Converts the containing data to a *new value* of type \p T and return this *value*.
  531. * If \p ok is non-null: \p *ok is set to `true` when the value was successfully converted to \p T; otherwise \p *ok is set to `false`.
  532. * The type \p T must meet the requirement to be *default constructible*.
  533. *
  534. * \code{.cpp}
  535. * variant val = 12;
  536. * if (val.can_convert<float>())
  537. * {
  538. * bool ok = false;
  539. * float result = val.convert<float>(&ok);
  540. * if (ok)
  541. * // ...
  542. * }
  543. * \endcode
  544. *
  545. * In order to enable a custom type conversion, a conversion function has to be registered
  546. * via \ref type::register_converter_func().
  547. *
  548. * \remark Before doing the conversion you should check whether it is in general possible to convert to type \p T
  549. * with the function \ref can_convert(). When the conversion fails, a default constructed value of type \p T is returned.
  550. *
  551. * \return The converted value as type \p T.
  552. *
  553. * \see can_convert(), type::register_converter_func()
  554. */
  555. template<typename T>
  556. T convert(bool* ok = nullptr) const;
  557. /*!
  558. * \brief Converts the containing data to the given value \p value and returns a `bool` flag that indicated whether the conversion
  559. * was successful or not.
  560. *
  561. * When you need to convert to a type which cannot be default constructed use this function.
  562. *
  563. * See following example code:
  564. * \code{.cpp}
  565. * variant val = 12;
  566. * if (val.can_convert<custom_type>())
  567. * {
  568. * custom_type obj(42); // non-default ctor type
  569. * bool result = val.convert(obj);
  570. * if (result)
  571. * // ...
  572. * }
  573. * \endcode
  574. *
  575. * In order to enable a custom type conversion, a conversion function has to be registered
  576. * via \ref type::register_converter_func().
  577. *
  578. * \remark Before doing the conversion you should check whether it is in general possible to convert to type \p T
  579. * with the function \ref can_convert()
  580. *
  581. * \return `True` if the contained data could be converted to \p value; otherwise `false`.
  582. *
  583. * \see can_convert(), type::register_converter_func()
  584. */
  585. template<typename T>
  586. bool convert(T& value) const;
  587. /*!
  588. * \brief Creates a \ref variant_associative_view from the containing value,
  589. * when the \ref variant::get_type "type" or its \ref type::get_raw_type() "raw type"
  590. * or the \ref type::get_wrapped_type() "wrapped type" is an \ref type::is_associative_container() "associative container".
  591. * Otherwise a default constructed variant_associative_view will be returned.
  592. *
  593. * A typical example is the following:
  594. *
  595. * \code{.cpp}
  596. * std::map<int, std::string> my_map;
  597. * my_map.insert({1, "One"});
  598. * my_map.insert({2, "Two"});
  599. * my_map.insert({3, "Three"});
  600. *
  601. * variant var = my_map; // copies the content of my_map into var
  602. * variant_associative_view view = var.create_associative_view(); // creates a view of the hold container in the variant (data is not copied!)
  603. * std::size_t x = view.get_size(); // return number of elements x = 3
  604. * for (auto& item : view) // iterates over all items stored in the container
  605. * {
  606. * auto key = item.first.extract_wrapped_value().to_string();
  607. * auto value = item.second.extract_wrapped_value().to_string();
  608. * std::cout << "key: " << key << " value: " << value << std::endl;
  609. * }
  610. * \endcode
  611. *
  612. * \remark This function will return an \ref variant_associative_view::is_valid() "invalid" object, when the \ref variant::get_type "type" is no associative container.
  613. *
  614. * \return A variant_associative_view object.
  615. *
  616. * \see can_convert(), convert()
  617. */
  618. variant_associative_view create_associative_view() const;
  619. /*!
  620. * \brief Creates a \ref variant_sequential_view from the containing value,
  621. * when the \ref variant::get_type "type" or its \ref type::get_raw_type() "raw type"
  622. * or the \ref type::get_wrapped_type() "wrapped type" is an \ref type::is_sequential_container() "sequential container".
  623. * Otherwise a default constructed variant_sequential_view will be returned.
  624. *
  625. * A typical example is the following:
  626. *
  627. * \code{.cpp}
  628. * std::vector<int> my_vec = { 1, 2, 3, 4, 5};
  629. * variant var = my_vec; // copies data into variant
  630. * if (var.is_sequential_container())
  631. * {
  632. * variant_sequential_view view = var.create_sequential_view(); // performs no copy of the underlying vector
  633. * std::cout << view.get_size() << std::endl; // prints: '5'
  634. * for (const auto& item : view) // iterates over all elements of the std::vector<T>
  635. * {
  636. * // remark that the value is stored inside a 'std::reference_wrapper', however there is an automatic conversion for wrapper classes implemented.
  637. * std::cout << "data: " << item.to_string() << " ";
  638. * }
  639. * }
  640. * \endcode
  641. *
  642. * \remark This function will return an \ref variant_sequential_view::is_valid() "invalid" object, when the \ref variant::get_type "type" is no sequential container.
  643. *
  644. * \return A variant_sequential_view object.
  645. *
  646. * \see can_convert(), convert()
  647. */
  648. variant_sequential_view create_sequential_view() const;
  649. /*!
  650. * \brief Returns the variant as a `bool` if this variant is of \ref is_type() "type" `bool`.
  651. *
  652. * Returns `true` if the variant contains an \ref type::is_arithmetic() "arithmetic type" which value is non-zero
  653. * or if the variant contains a `std::string` and its lower-case content is not one of the following:
  654. * `""` (empty), `"0"` or `"false"`; otherwise returns `false`.
  655. *
  656. * Also any user-defined \ref type::register_converter_func() "conversion function" from the
  657. * \ref is_type() "source type" to `bool` will be executed when necessary.
  658. *
  659. * \see can_convert(), is_type()
  660. *
  661. * \return A `bool` value.
  662. */
  663. bool to_bool() const;
  664. /*!
  665. * \brief Returns the containing variant as an `int` when the \ref is_type() "type" is an `integer`.
  666. *
  667. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `int`
  668. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `int`
  669. * will be executed when necessary.
  670. *
  671. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `int`; otherwise \p *ok is set to `false`.
  672. *
  673. * \remark A value overflow is not allowed, so if the internal value is larger than `int`, the conversion will fail.
  674. * Precision loss, such as in conversion from floating-point to `int` on platforms where they differ in size is allowed.
  675. * A conversion from `std::string` which contains non-numeric characters will fail.
  676. *
  677. * \see can_convert(), is_type()
  678. *
  679. * \return An `int` value.
  680. */
  681. int to_int(bool *ok = nullptr) const;
  682. /*!
  683. * \brief Returns the containing variant as a `float` when the \ref is_type() "type" is a `float`.
  684. *
  685. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `float`
  686. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `float`
  687. * will be executed when necessary.
  688. *
  689. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `float`; otherwise \p *ok is set to `false`.
  690. *
  691. * \remark A value overflow is not allowed, so if the internal value is larger than `float`, the conversion will fail.
  692. * Precision loss, such as in conversion from `double` to `float` on platforms where they differ in size is allowed.
  693. * A conversion from `std::string` which contains non-numeric characters will fail.
  694. *
  695. * \see can_convert(), is_type()
  696. *
  697. * \return A `float` value.
  698. */
  699. float to_float(bool* ok = nullptr) const;
  700. /*!
  701. * \brief Returns the containing variant as a `double` when the \ref is_type() "type" is a `double`.
  702. *
  703. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `double`
  704. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `double`
  705. * will be executed when necessary.
  706. *
  707. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `double`; otherwise \p *ok is set to `false`.
  708. *
  709. * \remark A value overflow is not allowed, so if the internal value is larger than `double`, the conversion will fail.
  710. * Precision loss, such as in conversion from `double` to `float` on platforms where they differ in size is allowed.
  711. * A conversion from `std::string` which contains non-numeric characters will fail.
  712. *
  713. * \see can_convert(), is_type()
  714. *
  715. * \return A `double` value.
  716. */
  717. double to_double(bool* ok = nullptr) const;
  718. /*!
  719. * \brief Returns the containing variant as a `std::string` when the \ref is_type() "type" is a `std::string`.
  720. *
  721. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" then a conversion to `std::string` will be done.
  722. * Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `std::string`
  723. * will be executed when necessary.
  724. *
  725. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `std::string`; otherwise \p *ok is set to `false`.
  726. *
  727. * \see can_convert(), is_type()
  728. *
  729. * \return A `std::string` value.
  730. */
  731. std::string to_string(bool *ok = nullptr) const;
  732. /*!
  733. * \brief Returns the containing variant as an `int8_t` when the \ref is_type() "type" is an `int8_t`.
  734. *
  735. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `int8_t`
  736. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `int8_t`
  737. * will be executed when necessary.
  738. *
  739. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `int8_t`; otherwise \p *ok is set to `false`.
  740. *
  741. * \remark A value overflow is not allowed, so if the internal value is larger than `int8_t`, the conversion will fail.
  742. * Precision loss, such as in conversion from floating-point to `int8_t` on platforms where they differ in size is allowed.
  743. * A conversion from `std::string` which contains non-numeric characters will fail.
  744. *
  745. * \see can_convert(), is_type()
  746. *
  747. * \return A `int8_t` value.
  748. */
  749. int8_t to_int8(bool *ok = nullptr) const;
  750. /*!
  751. * \brief Returns the containing variant as an `int16_t` when the \ref is_type() "type" is an `int16_t`.
  752. *
  753. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `int16_t`
  754. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `int16_t`
  755. * will be executed when necessary.
  756. *
  757. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `int16_t`; otherwise \p *ok is set to `false`.
  758. *
  759. * \remark A value overflow is not allowed, so if the internal value is larger than `int16_t`, the conversion will fail.
  760. * Precision loss, such as in conversion from floating-point to `int16_t` on platforms where they differ in size is allowed.
  761. * A conversion from `std::string` which contains non-numeric characters will fail.
  762. *
  763. * \see can_convert(), is_type()
  764. *
  765. * \return A `int16_t` value.
  766. */
  767. int16_t to_int16(bool *ok = nullptr) const;
  768. /*!
  769. * \brief Returns the containing variant as an `int32_t` when the \ref is_type() "type" is an `int32_t`.
  770. *
  771. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `int32_t`
  772. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `int32_t`
  773. * will be executed when necessary.
  774. *
  775. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `int32_t`; otherwise \p *ok is set to `false`.
  776. *
  777. * \remark A value overflow is not allowed, so if the internal value is larger than `int32_t`, the conversion will fail.
  778. * Precision loss, such as in conversion from floating-point to `int32_t` on platforms where they differ in size is allowed.
  779. * A conversion from `std::string` which contains non-numeric characters will fail.
  780. *
  781. * \see can_convert(), is_type()
  782. *
  783. * \return A `int32_t` value.
  784. */
  785. int32_t to_int32(bool *ok = nullptr) const;
  786. /*!
  787. * \brief Returns the containing variant as an `int64_t` when the \ref is_type() "type" is an `int64_t`.
  788. *
  789. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `int64_t`
  790. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `int64_t`
  791. * will be executed when necessary.
  792. *
  793. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `int64_t`; otherwise \p *ok is set to `false`.
  794. *
  795. * \remark A value overflow is not allowed, so if the internal value is larger than `int64_t`, the conversion will fail.
  796. * Precision loss, such as in conversion from floating-point to `int64_t` on platforms where they differ in size is allowed.
  797. * A conversion from `std::string` which contains non-numeric characters will fail.
  798. *
  799. * \see can_convert(), is_type()
  800. *
  801. * \return A `int64_t` value.
  802. */
  803. int64_t to_int64(bool *ok = nullptr) const;
  804. /*!
  805. * \brief Returns the containing variant as an `uint8_t` when the \ref is_type() "type" is an `uint8_t`.
  806. *
  807. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `uint8_t`
  808. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `uint8_t`
  809. * will be executed when necessary.
  810. *
  811. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `uint8_t`; otherwise \p *ok is set to `false`.
  812. *
  813. * \remark A value overflow is not allowed, so if the internal value is larger than `uint8_t`, the conversion will fail.
  814. * Also a loss of signedness is not allowed, that means a negative signed integer cannot be converted to `uint8_t`.
  815. * Precision loss, such as in conversion from floating-point to `uint8_t` on platforms where they differ in size is allowed.
  816. * A conversion from `std::string` which contains non-numeric characters will fail.
  817. *
  818. * \see can_convert(), is_type()
  819. *
  820. * \return A `uint8_t` value.
  821. */
  822. uint8_t to_uint8(bool *ok = nullptr) const;
  823. /*!
  824. * \brief Returns the containing variant as an `uint16_t` when the \ref is_type() "type" is an `uint16_t`.
  825. *
  826. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `uint16_t`
  827. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `uint16_t`
  828. * will be executed when necessary.
  829. *
  830. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `uint16_t`; otherwise \p *ok is set to `false`.
  831. *
  832. * \remark A value overflow is not allowed, so if the internal value is larger than `uint16_t`, the conversion will fail.
  833. * Also a loss of signedness is not allowed, that means a negative signed integer cannot be converted to `uint16_t`.
  834. * Precision loss, such as in conversion from floating-point to `uint16_t` on platforms where they differ in size is allowed.
  835. * A conversion from `std::string` which contains non-numeric characters will fail.
  836. *
  837. * \see can_convert(), is_type()
  838. *
  839. * \return A `uint16_t` value.
  840. */
  841. uint16_t to_uint16(bool *ok = nullptr) const;
  842. /*!
  843. * \brief Returns the containing variant as an `uint32_t` when the \ref is_type() "type" is an `uint32_t`.
  844. *
  845. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `uint32_t`
  846. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `uint32_t`
  847. * will be executed when necessary.
  848. *
  849. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `uint32_t`; otherwise \p *ok is set to `false`.
  850. *
  851. * \remark A value overflow is not allowed, so if the internal value is larger than `uint32_t`, the conversion will fail.
  852. * Also a loss of signedness is not allowed, that means a negative signed integer cannot be converted to `uint32_t`.
  853. * Precision loss, such as in conversion from floating-point to `uint32_t` on platforms where they differ in size is allowed.
  854. * A conversion from `std::string` which contains non-numeric characters will fail.
  855. *
  856. * \see can_convert(), is_type()
  857. *
  858. * \return A `uint32_t` value.
  859. */
  860. uint32_t to_uint32(bool *ok = nullptr) const;
  861. /*!
  862. * \brief Returns the containing variant as an `uint64_t` when the \ref is_type() "type" is an `uint64_t`.
  863. *
  864. * When the variant contains an \ref type::is_arithmetic() "arithmetic type" or an `std::string` then a conversion to `uint64_t`
  865. * will be tried. Also any user-defined \ref type::register_converter_func() "conversion function" from the \ref is_type() "source type" to `uint64_t`
  866. * will be executed when necessary.
  867. *
  868. * If \p ok is non-null: \p *ok is set to `true` if the value could be converted to an `uint8_t`; otherwise \p *ok is set to `false`.
  869. *
  870. * \remark A value overflow is not allowed, so if the internal value is larger than `uint64_t`, the conversion will fail.
  871. * Also a loss of signedness is not allowed, that means a negative signed integer cannot be converted to `uint64_t`.
  872. * Precision loss, such as in conversion from floating-point to `uint64_t` on platforms where they differ in size is allowed.
  873. * A conversion from `std::string` which contains non-numeric characters will fail.
  874. *
  875. * \see can_convert(), is_type()
  876. *
  877. * \return A `uint64_t` value.
  878. */
  879. uint64_t to_uint64(bool *ok = nullptr) const;
  880. private:
  881. /////////////////////////////////////////////////////////////////////////////////
  882. /*!
  883. * \brief Returns a pointer to the underlying data
  884. *
  885. * \remark You do not have to use this method directly.
  886. *
  887. * \return
  888. */
  889. RTTR_INLINE void* get_ptr() const;
  890. /*!
  891. * \brief Returns the type object of the underlying data
  892. *
  893. * \remark You do not have to use this method directly.
  894. *
  895. * \return Type object.
  896. */
  897. RTTR_INLINE type get_raw_type() const;
  898. /*!
  899. * \brief Returns a pointer to the underlying data.
  900. * This will return
  901. *
  902. * \remark You do not have to use this method directly.
  903. *
  904. * \return Raw void pointer.
  905. */
  906. RTTR_INLINE void* get_raw_ptr() const;
  907. //! Helper function to initialize all arithmetic types
  908. template<typename T>
  909. detail::enable_if_t<std::is_arithmetic<T>::value, T> convert_impl(bool* ok = nullptr) const;
  910. template<typename T>
  911. detail::enable_if_t<!std::is_arithmetic<T>::value && !std::is_enum<T>::value, T> convert_impl(bool* ok = nullptr) const;
  912. template<typename T>
  913. detail::enable_if_t<std::is_enum<T>::value, T> convert_impl(bool* ok = nullptr) const;
  914. /*!
  915. * \brief Returns a pointer to the underlying object pointer wrapped in a smart_ptr.
  916. *
  917. * \remark You do not have to use this method directly.
  918. *
  919. * \return Type object of the wrapped pointer object.
  920. */
  921. RTTR_INLINE detail::data_address_container get_data_address_container() const;
  922. bool convert(const type& target_type, variant& var) const;
  923. /*!
  924. * \brief Tries to convert the internal type to the given type \p to.
  925. *
  926. * \return `True`, when the conversion was successful, otherwise `false`.
  927. */
  928. template<typename T>
  929. bool try_basic_type_conversion(T& to) const;
  930. /*!
  931. * \brief Tries to convert the internal pointer type to the given pointer type \p T.
  932. *
  933. * \return `True`, when the conversion was successful, otherwise `false`.
  934. */
  935. template<typename T>
  936. typename std::enable_if<detail::pointer_count<T>::value == 1, bool>::type
  937. try_pointer_conversion(T& to, const type& source_type, const type& target_type) const;
  938. /*!
  939. * \brief A dummy method which does in fact always return `falsev.
  940. *
  941. * \return `False`.
  942. */
  943. template<typename T>
  944. typename std::enable_if<detail::pointer_count<T>::value != 1, bool>::type
  945. try_pointer_conversion(T& to, const type& source_type, const type& target_type) const;
  946. /*!
  947. * \brief Compares the containing and the given variant \p other for equality.
  948. *
  949. * \param ok \p ok is set to `true` if the value could be compared; otherwise \p ok is set to `false`.
  950. *
  951. * \return A boolean with value `true`, that indicates both variant's are equal, otherwise `false`.
  952. */
  953. bool compare_equal(const variant& other, bool& ok) const;
  954. /*!
  955. * \brief Compares the containing and the given variant \p other for less than.
  956. *
  957. * \param ok \p ok is set to `true` if the value could be compared; otherwise \p ok is set to `false`.
  958. *
  959. * \return A boolean with value `true`, that indicates this variant is less than the \p other, otherwise `false`.
  960. */
  961. bool compare_less(const variant& other, bool& ok) const;
  962. /*!
  963. * \brief A function to check whether the contained pointer type is a `nullptr` or not.
  964. *
  965. * \return A boolean with value `true`, when the contained value type is equal to `nullptr`; otherwise false.
  966. */
  967. RTTR_INLINE bool is_nullptr() const;
  968. variant create_wrapped_value(const type& wrapped_type) const;
  969. private:
  970. friend class argument;
  971. friend class instance;
  972. template<typename T, typename Tp, typename Converter>
  973. friend struct detail::variant_data_base_policy;
  974. friend struct detail::variant_data_policy_nullptr_t;
  975. friend RTTR_API bool detail::variant_compare_less(const variant&, const type&, const variant&, const type&, bool& ok);
  976. template<class T>
  977. friend RTTR_INLINE T* detail::unsafe_variant_cast(variant* operand) RTTR_NOEXCEPT;
  978. detail::variant_data m_data;
  979. detail::variant_policy_func m_policy;
  980. };
  981. /////////////////////////////////////////////////////////////////////////////////////////
  982. /*!
  983. * \brief Returns a reference to the containing value as type \p T.
  984. *
  985. * \code{.cpp}
  986. *
  987. * variant var = std::string("hello world");
  988. * std:string& value_ref = variant_cast<std::string&>(var); // extracts the value by reference
  989. * std:string value = variant_cast<std::string>(var); // copies the value
  990. *
  991. * \endcode
  992. *
  993. * \remark Extracting a value type, which is not stored in the variant, leads to undefined behaviour.
  994. * No exception or error code will be returned!
  995. */
  996. template<class T>
  997. T variant_cast(const variant& operand);
  998. /*!
  999. * \brief Returns a reference to the containing value as type \p T.
  1000. *
  1001. * \code{.cpp}
  1002. *
  1003. * variant var = std::string("hello world");
  1004. * std::string& value_ref = variant_cast<std::string&>(var); // extracts the value by reference
  1005. * std::string value = variant_cast<std::string>(var); // copies the value
  1006. *
  1007. * \endcode
  1008. *
  1009. * \remark Extracting a value type, which is not stored in the variant, leads to undefined behaviour.
  1010. * No exception or error code will be returned!
  1011. */
  1012. template<class T>
  1013. T variant_cast(variant& operand);
  1014. /*!
  1015. * \brief Move the containing value from the variant into a type \p T.
  1016. *
  1017. * \code{.cpp}
  1018. *
  1019. * variant var = std::string("hello world");
  1020. * std::string& a = variant_cast<std::string&>(var);
  1021. * std::string b = variant_cast<std::string>(std::move(var)); // move the value to 'b'
  1022. * std::cout << "a: " << a << std::endl; // is now empty (nothing to print)
  1023. * std::cout << "b: " << b << std::endl; // prints "hello world"
  1024. *
  1025. * \endcode
  1026. *
  1027. * \remark Extracting a value type, which is not stored in the variant, leads to undefined behaviour.
  1028. * No exception or error code will be returned!
  1029. */
  1030. template<class T>
  1031. T variant_cast(variant&& operand);
  1032. /*!
  1033. * \brief Returns a pointer to the containing value with type \p T.
  1034. * When the containing value is of type \p T, a valid pointer to the type will be returned.
  1035. * Otherwise a `nullptr` is returned.
  1036. *
  1037. * \code{.cpp}
  1038. *
  1039. * variant var = std::string("hello world");
  1040. * std:string* a = variant_cast<std::string>(&var); // performs an internal type check and returns the value by reference
  1041. * int* b = variant_cast<int>(&var);
  1042. * std::cout << "a valid: " << a != nullptr << std::endl; // prints "1"
  1043. * std::cout << "b valid: " << b != nullptr << std::endl; // prints "0"
  1044. * \endcode
  1045. *
  1046. * \return A valid pointer, when the containing type is of type \p T; otherwise a `nullptr`.
  1047. */
  1048. template<class T>
  1049. const T* variant_cast(const variant* operand) RTTR_NOEXCEPT;
  1050. /*!
  1051. * \brief Returns a pointer to the containing value with type \p T.
  1052. * When the containing value is of type \p T, a valid pointer to the type will be returned.
  1053. * Otherwise a `nullptr` is returned.
  1054. *
  1055. * \code{.cpp}
  1056. *
  1057. * variant var = std::string("hello world");
  1058. * std:string* a = variant_cast<std::string>(&var); // performs an internal type check and returns the value by reference
  1059. * int* b = variant_cast<int>(&var);
  1060. * std::cout << "a valid: " << a != nullptr << std::endl; // prints "1"
  1061. * std::cout << "b valid: " << b != nullptr << std::endl; // prints "0"
  1062. * \endcode
  1063. *
  1064. * \return A valid pointer, when the containing type is of type \p T; otherwise a `nullptr`.
  1065. */
  1066. template<class T>
  1067. T* variant_cast(variant* operand) RTTR_NOEXCEPT;
  1068. } // end namespace rttr
  1069. #include "rttr/detail/variant/variant_impl.h"
  1070. #endif // RTTR_VARIANT_H_