variant_data_converter.h 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457
  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_DATA_CONVERTER_H_
  28. #define RTTR_VARIANT_DATA_CONVERTER_H_
  29. #include "rttr/detail/conversion/std_conversion_functions.h"
  30. #include "rttr/detail/conversion/number_conversion.h"
  31. #include "rttr/detail/enumeration/enumeration_helper.h"
  32. namespace rttr
  33. {
  34. class argument;
  35. namespace detail
  36. {
  37. template<typename T>
  38. struct convert_from;
  39. /////////////////////////////////////////////////////////////////////////////////////////
  40. /*!
  41. * The default converter manager class.
  42. *
  43. * It will check at runtime the incoming argument type and will forward its value to the corresponding conversion function.
  44. * All basic fixed integer and floating-point (float, double) types are handled.
  45. *
  46. * \remark Custom types will not be handled here,
  47. * therefore a converter function has to be registered explicitly. See \ref type::register_converter_func.
  48. * With this class we can avoid this step.
  49. */
  50. template<typename T, typename Type_Converter = convert_from<T>>
  51. struct default_type_converter
  52. {
  53. static bool convert_to(const T& value, argument& arg)
  54. {
  55. const type target_type = arg.get_type();
  56. if (target_type == type::get<bool>())
  57. return Type_Converter::to(value, arg.get_value<bool>());
  58. else if (target_type == type::get<char>())
  59. return Type_Converter::to(value, arg.get_value<char>());
  60. else if (target_type == type::get<int8_t>())
  61. return Type_Converter::to(value, arg.get_value<int8_t>());
  62. else if (target_type == type::get<int16_t>())
  63. return Type_Converter::to(value, arg.get_value<int16_t>());
  64. else if (target_type == type::get<int32_t>())
  65. return Type_Converter::to(value, arg.get_value<int32_t>());
  66. else if (target_type == type::get<int64_t>())
  67. return Type_Converter::to(value, arg.get_value<int64_t>());
  68. else if (target_type == type::get<uint8_t>())
  69. return Type_Converter::to(value, arg.get_value<uint8_t>());
  70. else if (target_type == type::get<uint16_t>())
  71. return Type_Converter::to(value, arg.get_value<uint16_t>());
  72. else if (target_type == type::get<uint32_t>())
  73. return Type_Converter::to(value, arg.get_value<uint32_t>());
  74. else if (target_type == type::get<uint64_t>())
  75. return Type_Converter::to(value, arg.get_value<uint64_t>());
  76. else if (target_type == type::get<float>())
  77. return Type_Converter::to(value, arg.get_value<float>());
  78. else if (target_type == type::get<double>())
  79. return Type_Converter::to(value, arg.get_value<double>());
  80. else if (target_type == type::get<std::string>())
  81. return Type_Converter::to(value, arg.get_value<std::string>());
  82. else if (is_variant_with_enum(arg))
  83. return Type_Converter::to_enum(value, arg);
  84. else
  85. return false;
  86. }
  87. };
  88. /////////////////////////////////////////////////////////////////////////////////////////
  89. /*!
  90. * The empty converter class, does nothing. The only purpose is to avoid a compile time error.
  91. * The conversion of custom types will be handled via registered conversion functions. See \ref type::register_converter_func.
  92. */
  93. template<typename T>
  94. struct empty_type_converter
  95. {
  96. static RTTR_INLINE bool convert_to(const T& value, argument& arg)
  97. {
  98. return false;
  99. }
  100. };
  101. /////////////////////////////////////////////////////////////////////////////////////////
  102. /*!
  103. * The default implementation of the converter class for all basic types.
  104. *
  105. * That are:
  106. * - all integral fixed types: int8_t till uint64_t
  107. * - all floating point types
  108. * - std::string
  109. */
  110. template<typename T>
  111. struct convert_from
  112. {
  113. static RTTR_INLINE bool to(const T& from, bool& to)
  114. {
  115. return false;
  116. }
  117. static RTTR_INLINE bool to(const T& from, char& to)
  118. {
  119. return false;
  120. }
  121. static RTTR_INLINE bool to(const T& from, int8_t& to)
  122. {
  123. return false;
  124. }
  125. static RTTR_INLINE bool to(const T& from, int16_t& to)
  126. {
  127. return false;
  128. }
  129. static RTTR_INLINE bool to(const T& from, int32_t& to)
  130. {
  131. return false;
  132. }
  133. static RTTR_INLINE bool to(const T& from, int64_t& to)
  134. {
  135. return false;
  136. }
  137. static RTTR_INLINE bool to(const T& from, uint8_t& to)
  138. {
  139. return false;
  140. }
  141. static RTTR_INLINE bool to(const T& from, uint16_t& to)
  142. {
  143. return false;
  144. }
  145. static RTTR_INLINE bool to(const T& from, uint32_t& to)
  146. {
  147. return false;
  148. }
  149. static RTTR_INLINE bool to(const T& from, uint64_t& to)
  150. {
  151. return false;
  152. }
  153. static RTTR_INLINE bool to(const T& from, float& to)
  154. {
  155. return false;
  156. }
  157. static RTTR_INLINE bool to(const T& from, double& to)
  158. {
  159. return false;
  160. }
  161. static RTTR_INLINE bool to(const T& from, std::string& to)
  162. {
  163. return false;
  164. }
  165. static RTTR_INLINE bool to_enum(const T& from, argument& to)
  166. {
  167. return false;
  168. }
  169. };
  170. /////////////////////////////////////////////////////////////////////////////////////////
  171. /////////////////////////////////////////////////////////////////////////////////////////
  172. /////////////////////////////////////////////////////////////////////////////////////////
  173. // here come the specialization for several atomic types
  174. template<>
  175. struct RTTR_API convert_from<bool>
  176. {
  177. static RTTR_INLINE bool to(const bool& from, bool& to)
  178. {
  179. to = from;
  180. return true;
  181. }
  182. static RTTR_INLINE bool to(const bool& from, char& to)
  183. {
  184. to = static_cast<char>(from ? 1 : 0);
  185. return true;
  186. }
  187. static RTTR_INLINE bool to(const bool& from, int8_t& to)
  188. {
  189. to = static_cast<int8_t>(from ? 1 : 0);
  190. return true;
  191. }
  192. static RTTR_INLINE bool to(const bool& from, int16_t& to)
  193. {
  194. to = static_cast<int16_t>(from ? 1 : 0);
  195. return true;
  196. }
  197. static RTTR_INLINE bool to(const bool& from, int32_t& to)
  198. {
  199. to = static_cast<int32_t>(from ? 1 : 0);
  200. return true;
  201. }
  202. static RTTR_INLINE bool to(const bool& from, int64_t& to)
  203. {
  204. to = static_cast<int64_t>(from ? 1 : 0);
  205. return true;
  206. }
  207. static RTTR_INLINE bool to(const bool& from, uint8_t& to)
  208. {
  209. to = static_cast<uint8_t>(from ? 1 : 0);
  210. return true;
  211. }
  212. static RTTR_INLINE bool to(const bool& from, uint16_t& to)
  213. {
  214. to = static_cast<uint16_t>(from ? 1 : 0);
  215. return true;
  216. }
  217. static RTTR_INLINE bool to(const bool& from, uint32_t& to)
  218. {
  219. to = static_cast<uint32_t>(from ? 1 : 0);
  220. return true;
  221. }
  222. static RTTR_INLINE bool to(const bool& from, uint64_t& to)
  223. {
  224. to = static_cast<uint64_t>(from ? 1 : 0);
  225. return true;
  226. }
  227. static RTTR_INLINE bool to(const bool& from, float& to)
  228. {
  229. to = static_cast<float>(from ? 1.0f : 0.0f);
  230. return true;
  231. }
  232. static RTTR_INLINE bool to(const bool& from, double& to)
  233. {
  234. to = static_cast<double>(from ? 1.0 : 0.0);
  235. return true;
  236. }
  237. static RTTR_INLINE bool to(const bool& from, std::string& to)
  238. {
  239. to = (from ? "true" : "false");
  240. return true;
  241. }
  242. static RTTR_INLINE bool to_enum(const bool& from, argument& to)
  243. {
  244. return to_enumeration(from, to);
  245. }
  246. };
  247. /////////////////////////////////////////////////////////////////////////////////////////
  248. template<>
  249. struct RTTR_API convert_from<char>
  250. {
  251. static RTTR_INLINE bool to(const char& from, bool& to)
  252. {
  253. to = (from != '\0');
  254. return true;
  255. }
  256. static RTTR_INLINE bool to(const char& from, char& to)
  257. {
  258. to = from;
  259. return true;
  260. }
  261. static RTTR_INLINE bool to(const char& from, int8_t& to)
  262. {
  263. to = static_cast<int8_t>(from);
  264. return true;
  265. }
  266. static RTTR_INLINE bool to(const char& from, int16_t& to)
  267. {
  268. to = static_cast<int16_t>(from);
  269. return true;
  270. }
  271. static RTTR_INLINE bool to(const char& from, int32_t& to)
  272. {
  273. to = static_cast<int32_t>(from);
  274. return true;
  275. }
  276. static RTTR_INLINE bool to(const char& from, int64_t& to)
  277. {
  278. to = static_cast<int64_t>(from);
  279. return true;
  280. }
  281. static RTTR_INLINE bool to(const char& from, uint8_t& to)
  282. {
  283. return convert_to(from, to);
  284. }
  285. static RTTR_INLINE bool to(const char& from, uint16_t& to)
  286. {
  287. return convert_to(from, to);
  288. }
  289. static RTTR_INLINE bool to(const char& from, uint32_t& to)
  290. {
  291. return convert_to(from, to);
  292. }
  293. static RTTR_INLINE bool to(const char& from, uint64_t& to)
  294. {
  295. return convert_to(from, to);
  296. }
  297. static RTTR_INLINE bool to(const char& from, float& to)
  298. {
  299. to = static_cast<float>(from);
  300. return true;
  301. }
  302. static RTTR_INLINE bool to(const char& from, double& to)
  303. {
  304. to = static_cast<double>(from);
  305. return true;
  306. }
  307. static RTTR_INLINE bool to(const char& from, std::string& to)
  308. {
  309. to = std::string(1, from);
  310. return true;
  311. }
  312. static RTTR_INLINE bool to_enum(const char& from, argument& to)
  313. {
  314. return to_enumeration(from, to);
  315. }
  316. };
  317. /////////////////////////////////////////////////////////////////////////////////////////
  318. template<>
  319. struct RTTR_API convert_from<int8_t>
  320. {
  321. static RTTR_INLINE bool to(const int8_t& from, bool& to)
  322. {
  323. to = (from != 0);
  324. return true;
  325. }
  326. static RTTR_INLINE bool to(const int8_t& from, char& to)
  327. {
  328. to = static_cast<char>(from);
  329. return true;
  330. }
  331. static RTTR_INLINE bool to(const int8_t& from, int8_t& to)
  332. {
  333. to = from;
  334. return true;
  335. }
  336. static RTTR_INLINE bool to(const int8_t& from, int16_t& to)
  337. {
  338. to = from;
  339. return true;
  340. }
  341. static RTTR_INLINE bool to(const int8_t& from, int32_t& to)
  342. {
  343. to = from;
  344. return true;
  345. }
  346. static RTTR_INLINE bool to(const int8_t& from, int64_t& to)
  347. {
  348. to = from;
  349. return true;
  350. }
  351. static RTTR_INLINE bool to(const int8_t& from, uint8_t& to)
  352. {
  353. return convert_to(from, to);
  354. }
  355. static RTTR_INLINE bool to(const int8_t& from, uint16_t& to)
  356. {
  357. return convert_to(from, to);
  358. }
  359. static RTTR_INLINE bool to(const int8_t& from, uint32_t& to)
  360. {
  361. return convert_to(from, to);
  362. }
  363. static RTTR_INLINE bool to(const int8_t& from, uint64_t& to)
  364. {
  365. return convert_to(from, to);
  366. }
  367. static RTTR_INLINE bool to(const int8_t& from, float& to)
  368. {
  369. to = static_cast<float>(from);
  370. return true;
  371. }
  372. static RTTR_INLINE bool to(const int8_t& from, double& to)
  373. {
  374. to = static_cast<double>(from);
  375. return true;
  376. }
  377. static RTTR_INLINE bool to(const int8_t& from, std::string& to)
  378. {
  379. return convert_to(from, to);
  380. }
  381. static RTTR_INLINE bool to_enum(const int8_t& from, argument& to)
  382. {
  383. return to_enumeration(from, to);
  384. }
  385. };
  386. /////////////////////////////////////////////////////////////////////////////////////////
  387. template<>
  388. struct RTTR_API convert_from<int16_t>
  389. {
  390. static RTTR_INLINE bool to(const int16_t& from, bool& to)
  391. {
  392. to = (from != 0);
  393. return true;
  394. }
  395. static RTTR_INLINE bool to(const int16_t& from, char& to)
  396. {
  397. return convert_to(from, to);
  398. }
  399. static RTTR_INLINE bool to(const int16_t& from, int8_t& to)
  400. {
  401. return convert_to(from, to);
  402. }
  403. static RTTR_INLINE bool to(const int16_t& from, int16_t& to)
  404. {
  405. to = from;
  406. return true;
  407. }
  408. static RTTR_INLINE bool to(const int16_t& from, int32_t& to)
  409. {
  410. to = from;
  411. return true;
  412. }
  413. static RTTR_INLINE bool to(const int16_t& from, int64_t& to)
  414. {
  415. to = from;
  416. return true;
  417. }
  418. static RTTR_INLINE bool to(const int16_t& from, uint8_t& to)
  419. {
  420. return convert_to(from, to);
  421. }
  422. static RTTR_INLINE bool to(const int16_t& from, uint16_t& to)
  423. {
  424. return convert_to(from, to);
  425. }
  426. static RTTR_INLINE bool to(const int16_t& from, uint32_t& to)
  427. {
  428. return convert_to(from, to);
  429. }
  430. static RTTR_INLINE bool to(const int16_t& from, uint64_t& to)
  431. {
  432. return convert_to(from, to);
  433. }
  434. static RTTR_INLINE bool to(const int16_t& from, float& to)
  435. {
  436. to = static_cast<float>(from);
  437. return true;
  438. }
  439. static RTTR_INLINE bool to(const int16_t& from, double& to)
  440. {
  441. to = static_cast<double>(from);
  442. return true;
  443. }
  444. static RTTR_INLINE bool to(const int16_t& from, std::string& to)
  445. {
  446. return convert_to(from, to);
  447. }
  448. static RTTR_INLINE bool to_enum(const int16_t& from, argument& to)
  449. {
  450. return to_enumeration(from, to);
  451. }
  452. };
  453. /////////////////////////////////////////////////////////////////////////////////////////
  454. template<>
  455. struct RTTR_API convert_from<int32_t>
  456. {
  457. static RTTR_INLINE bool to(const int32_t& from, bool& to)
  458. {
  459. to = (from != 0);
  460. return true;
  461. }
  462. static RTTR_INLINE bool to(const int32_t& from, char& to)
  463. {
  464. return convert_to(from, to);
  465. }
  466. static RTTR_INLINE bool to(const int32_t& from, int8_t& to)
  467. {
  468. return convert_to(from, to);
  469. }
  470. static RTTR_INLINE bool to(const int32_t& from, int16_t& to)
  471. {
  472. return convert_to(from, to);
  473. }
  474. static RTTR_INLINE bool to(const int32_t& from, int32_t& to)
  475. {
  476. to = from;
  477. return true;
  478. }
  479. static RTTR_INLINE bool to(const int32_t& from, int64_t& to)
  480. {
  481. to = from;
  482. return true;
  483. }
  484. static RTTR_INLINE bool to(const int32_t& from, uint8_t& to)
  485. {
  486. return convert_to(from, to);
  487. }
  488. static RTTR_INLINE bool to(const int32_t& from, uint16_t& to)
  489. {
  490. return convert_to(from, to);
  491. }
  492. static RTTR_INLINE bool to(const int32_t& from, uint32_t& to)
  493. {
  494. return convert_to(from, to);
  495. }
  496. static RTTR_INLINE bool to(const int32_t& from, uint64_t& to)
  497. {
  498. return convert_to(from, to);
  499. }
  500. static RTTR_INLINE bool to(const int32_t& from, float& to)
  501. {
  502. to = static_cast<float>(from);
  503. return true;
  504. }
  505. static RTTR_INLINE bool to(const int32_t& from, double& to)
  506. {
  507. to = static_cast<double>(from);
  508. return true;
  509. }
  510. static RTTR_INLINE bool to(const int32_t& from, std::string& to)
  511. {
  512. return convert_to(from, to);
  513. }
  514. static RTTR_INLINE bool to_enum(const int32_t& from, argument& to)
  515. {
  516. return to_enumeration(from, to);
  517. }
  518. };
  519. /////////////////////////////////////////////////////////////////////////////////////////
  520. template<>
  521. struct RTTR_API convert_from<int64_t>
  522. {
  523. static RTTR_INLINE bool to(const int64_t& from, bool& to)
  524. {
  525. to = (from != 0);
  526. return true;
  527. }
  528. static RTTR_INLINE bool to(const int64_t& from, char& to)
  529. {
  530. return convert_to(from, to);
  531. }
  532. static RTTR_INLINE bool to(const int64_t& from, int8_t& to)
  533. {
  534. return convert_to(from, to);
  535. }
  536. static RTTR_INLINE bool to(const int64_t& from, int16_t& to)
  537. {
  538. return convert_to(from, to);
  539. }
  540. static RTTR_INLINE bool to(const int64_t& from, int32_t& to)
  541. {
  542. return convert_to(from, to);
  543. }
  544. static RTTR_INLINE bool to(const int64_t& from, int64_t& to)
  545. {
  546. to = from;
  547. return true;
  548. }
  549. static RTTR_INLINE bool to(const int64_t& from, uint8_t& to)
  550. {
  551. return convert_to(from, to);
  552. }
  553. static RTTR_INLINE bool to(const int64_t& from, uint16_t& to)
  554. {
  555. return convert_to(from, to);
  556. }
  557. static RTTR_INLINE bool to(const int64_t& from, uint32_t& to)
  558. {
  559. return convert_to(from, to);
  560. }
  561. static RTTR_INLINE bool to(const int64_t& from, uint64_t& to)
  562. {
  563. return convert_to(from, to);
  564. }
  565. static RTTR_INLINE bool to(const int64_t& from, float& to)
  566. {
  567. to = static_cast<float>(from);
  568. return true;
  569. }
  570. static RTTR_INLINE bool to(const int64_t& from, double& to)
  571. {
  572. to = static_cast<double>(from);
  573. return true;
  574. }
  575. static RTTR_INLINE bool to(const int64_t& from, std::string& to)
  576. {
  577. return convert_to(from, to);
  578. }
  579. static RTTR_INLINE bool to_enum(const int64_t& from, argument& to)
  580. {
  581. return to_enumeration(from, to);
  582. }
  583. };
  584. /////////////////////////////////////////////////////////////////////////////////////////
  585. /////////////////////////////////////////////////////////////////////////////////////////
  586. /////////////////////////////////////////////////////////////////////////////////////////
  587. template<>
  588. struct RTTR_API convert_from<uint8_t>
  589. {
  590. static RTTR_INLINE bool to(const uint8_t& from, bool& to)
  591. {
  592. to = (from != 0);
  593. return true;
  594. }
  595. static RTTR_INLINE bool to(const uint8_t& from, char& to)
  596. {
  597. return convert_to(from, to);
  598. }
  599. static RTTR_INLINE bool to(const uint8_t& from, int8_t& to)
  600. {
  601. return convert_to(from, to);
  602. }
  603. static RTTR_INLINE bool to(const uint8_t& from, int16_t& to)
  604. {
  605. return convert_to(from, to);
  606. }
  607. static RTTR_INLINE bool to(const uint8_t& from, int32_t& to)
  608. {
  609. to = static_cast<int32_t>(from);
  610. return true;
  611. }
  612. static RTTR_INLINE bool to(const uint8_t& from, int64_t& to)
  613. {
  614. to = static_cast<int64_t>(from);
  615. return true;
  616. }
  617. static RTTR_INLINE bool to(const uint8_t& from, uint8_t& to)
  618. {
  619. to = from;
  620. return true;
  621. }
  622. static RTTR_INLINE bool to(const uint8_t& from, uint16_t& to)
  623. {
  624. to = from;
  625. return true;
  626. }
  627. static RTTR_INLINE bool to(const uint8_t& from, uint32_t& to)
  628. {
  629. to = from;
  630. return true;
  631. }
  632. static RTTR_INLINE bool to(const uint8_t& from, uint64_t& to)
  633. {
  634. to = from;
  635. return true;
  636. }
  637. static RTTR_INLINE bool to(const uint8_t& from, float& to)
  638. {
  639. to = static_cast<float>(from);
  640. return true;
  641. }
  642. static RTTR_INLINE bool to(const uint8_t& from, double& to)
  643. {
  644. to = static_cast<double>(from);
  645. return true;
  646. }
  647. static RTTR_INLINE bool to(const uint8_t& from, std::string& to)
  648. {
  649. return convert_to(from, to);
  650. }
  651. static RTTR_INLINE bool to_enum(const uint8_t& from, argument& to)
  652. {
  653. return to_enumeration(from, to);
  654. }
  655. };
  656. /////////////////////////////////////////////////////////////////////////////////////////
  657. template<>
  658. struct RTTR_API convert_from<uint16_t>
  659. {
  660. static RTTR_INLINE bool to(const uint16_t& from, bool& to)
  661. {
  662. to = (from != 0);
  663. return true;
  664. }
  665. static RTTR_INLINE bool to(const uint16_t& from, char& to)
  666. {
  667. return convert_to(from, to);
  668. }
  669. static RTTR_INLINE bool to(const uint16_t& from, int8_t& to)
  670. {
  671. return convert_to(from, to);
  672. }
  673. static RTTR_INLINE bool to(const uint16_t& from, int16_t& to)
  674. {
  675. return convert_to(from, to);
  676. }
  677. static RTTR_INLINE bool to(const uint16_t& from, int32_t& to)
  678. {
  679. return convert_to(from, to);
  680. }
  681. static RTTR_INLINE bool to(const uint16_t& from, int64_t& to)
  682. {
  683. to = static_cast<int64_t>(from);
  684. return true;
  685. }
  686. static RTTR_INLINE bool to(const uint16_t& from, uint8_t& to)
  687. {
  688. return convert_to(from, to);
  689. }
  690. static RTTR_INLINE bool to(const uint16_t& from, uint16_t& to)
  691. {
  692. to = from;
  693. return true;
  694. }
  695. static RTTR_INLINE bool to(const uint16_t& from, uint32_t& to)
  696. {
  697. to = from;
  698. return true;
  699. }
  700. static RTTR_INLINE bool to(const uint16_t& from, uint64_t& to)
  701. {
  702. to = from;
  703. return true;
  704. }
  705. static RTTR_INLINE bool to(const uint16_t& from, float& to)
  706. {
  707. to = static_cast<float>(from);
  708. return true;
  709. }
  710. static RTTR_INLINE bool to(const uint16_t& from, double& to)
  711. {
  712. to = static_cast<double>(from);
  713. return true;
  714. }
  715. static RTTR_INLINE bool to(const uint16_t& from, std::string& to)
  716. {
  717. return convert_to(from, to);
  718. }
  719. static RTTR_INLINE bool to_enum(const uint16_t& from, argument& to)
  720. {
  721. return to_enumeration(from, to);
  722. }
  723. };
  724. /////////////////////////////////////////////////////////////////////////////////////////
  725. template<>
  726. struct RTTR_API convert_from<uint32_t>
  727. {
  728. static RTTR_INLINE bool to(const uint32_t& from, bool& to)
  729. {
  730. to = (from != 0);
  731. return true;
  732. }
  733. static RTTR_INLINE bool to(const uint32_t& from, char& to)
  734. {
  735. return convert_to(from, to);
  736. }
  737. static RTTR_INLINE bool to(const uint32_t& from, int8_t& to)
  738. {
  739. return convert_to(from, to);
  740. }
  741. static RTTR_INLINE bool to(const uint32_t& from, int16_t& to)
  742. {
  743. return convert_to(from, to);
  744. }
  745. static RTTR_INLINE bool to(const uint32_t& from, int32_t& to)
  746. {
  747. return convert_to(from, to);
  748. }
  749. static RTTR_INLINE bool to(const uint32_t& from, int64_t& to)
  750. {
  751. return convert_to(from, to);
  752. }
  753. static RTTR_INLINE bool to(const uint32_t& from, uint8_t& to)
  754. {
  755. return convert_to(from, to);
  756. }
  757. static RTTR_INLINE bool to(const uint32_t& from, uint16_t& to)
  758. {
  759. return convert_to(from, to);
  760. }
  761. static RTTR_INLINE bool to(const uint32_t& from, uint32_t& to)
  762. {
  763. to = from;
  764. return true;
  765. }
  766. static RTTR_INLINE bool to(const uint32_t& from, uint64_t& to)
  767. {
  768. to = from;
  769. return true;
  770. }
  771. static RTTR_INLINE bool to(const uint32_t& from, float& to)
  772. {
  773. to = static_cast<float>(from);
  774. return true;
  775. }
  776. static RTTR_INLINE bool to(const uint32_t& from, double& to)
  777. {
  778. to = static_cast<double>(from);
  779. return true;
  780. }
  781. static RTTR_INLINE bool to(const uint32_t& from, std::string& to)
  782. {
  783. return convert_to(from, to);
  784. }
  785. static RTTR_INLINE bool to_enum(const uint32_t& from, argument& to)
  786. {
  787. return to_enumeration(from, to);
  788. }
  789. };
  790. /////////////////////////////////////////////////////////////////////////////////////////
  791. template<>
  792. struct RTTR_API convert_from<uint64_t>
  793. {
  794. static RTTR_INLINE bool to(const uint64_t& from, bool& to)
  795. {
  796. to = (from != 0);
  797. return true;
  798. }
  799. static RTTR_INLINE bool to(const uint64_t& from, char& to)
  800. {
  801. return convert_to(from, to);
  802. }
  803. static RTTR_INLINE bool to(const uint64_t& from, int8_t& to)
  804. {
  805. return convert_to(from, to);
  806. }
  807. static RTTR_INLINE bool to(const uint64_t& from, int16_t& to)
  808. {
  809. return convert_to(from, to);
  810. }
  811. static RTTR_INLINE bool to(const uint64_t& from, int32_t& to)
  812. {
  813. return convert_to(from, to);
  814. }
  815. static RTTR_INLINE bool to(const uint64_t& from, int64_t& to)
  816. {
  817. return convert_to(from, to);
  818. }
  819. static RTTR_INLINE bool to(const uint64_t& from, uint8_t& to)
  820. {
  821. return convert_to(from, to);
  822. }
  823. static RTTR_INLINE bool to(const uint64_t& from, uint16_t& to)
  824. {
  825. return convert_to(from, to);
  826. }
  827. static RTTR_INLINE bool to(const uint64_t& from, uint32_t& to)
  828. {
  829. return convert_to(from, to);
  830. }
  831. static RTTR_INLINE bool to(const uint64_t& from, uint64_t& to)
  832. {
  833. to = from;
  834. return true;
  835. }
  836. static RTTR_INLINE bool to(const uint64_t& from, float& to)
  837. {
  838. to = static_cast<float>(from);
  839. return true;
  840. }
  841. static RTTR_INLINE bool to(const uint64_t& from, double& to)
  842. {
  843. to = static_cast<double>(from);
  844. return true;
  845. }
  846. static RTTR_INLINE bool to(const uint64_t& from, std::string& to)
  847. {
  848. return convert_to(from, to);
  849. }
  850. static RTTR_INLINE bool to_enum(const uint64_t& from, argument& to)
  851. {
  852. return to_enumeration(from, to);
  853. }
  854. };
  855. /////////////////////////////////////////////////////////////////////////////////////////
  856. template<>
  857. struct RTTR_API convert_from<float>
  858. {
  859. static RTTR_INLINE bool to(const float& from, bool& to)
  860. {
  861. to = !(from <= (std::numeric_limits<float>::min)() &&
  862. from >= -1 * (std::numeric_limits<float>::min)());
  863. return true;
  864. }
  865. static RTTR_INLINE bool to(const float& from, char& to)
  866. {
  867. return convert_to(from, to);
  868. }
  869. static RTTR_INLINE bool to(const float& from, int8_t& to)
  870. {
  871. return convert_to(from, to);
  872. }
  873. static RTTR_INLINE bool to(const float& from, int16_t& to)
  874. {
  875. return convert_to(from, to);
  876. }
  877. static RTTR_INLINE bool to(const float& from, int32_t& to)
  878. {
  879. return convert_to(from, to);
  880. }
  881. static RTTR_INLINE bool to(const float& from, int64_t& to)
  882. {
  883. return convert_to(from, to);
  884. }
  885. static RTTR_INLINE bool to(const float& from, uint8_t& to)
  886. {
  887. return convert_to(from, to);
  888. }
  889. static RTTR_INLINE bool to(const float& from, uint16_t& to)
  890. {
  891. return convert_to(from, to);
  892. }
  893. static RTTR_INLINE bool to(const float& from, uint32_t& to)
  894. {
  895. return convert_to(from, to);
  896. }
  897. static RTTR_INLINE bool to(const float& from, uint64_t& to)
  898. {
  899. return convert_to(from, to);
  900. }
  901. static RTTR_INLINE bool to(const float& from, float& to)
  902. {
  903. to = from;
  904. return true;
  905. }
  906. static RTTR_INLINE bool to(const float& from, double& to)
  907. {
  908. to = from;
  909. return true;
  910. }
  911. static RTTR_INLINE bool to(const float& from, std::string& to)
  912. {
  913. return convert_to(from, to);
  914. }
  915. static RTTR_INLINE bool to_enum(const float& from, argument& to)
  916. {
  917. return to_enumeration(from, to);
  918. }
  919. };
  920. /////////////////////////////////////////////////////////////////////////////////////////
  921. template<>
  922. struct RTTR_API convert_from<double>
  923. {
  924. static RTTR_INLINE bool to(const double& from, bool& to)
  925. {
  926. to = !(from <= (std::numeric_limits<double>::min)() &&
  927. from >= -1 * (std::numeric_limits<double>::min)());
  928. return true;
  929. }
  930. static RTTR_INLINE bool to(const double& from, char& to)
  931. {
  932. return convert_to(from, to);
  933. }
  934. static RTTR_INLINE bool to(const double& from, int8_t& to)
  935. {
  936. return convert_to(from, to);
  937. }
  938. static RTTR_INLINE bool to(const double& from, int16_t& to)
  939. {
  940. return convert_to(from, to);
  941. }
  942. static RTTR_INLINE bool to(const double& from, int32_t& to)
  943. {
  944. return convert_to(from, to);
  945. }
  946. static RTTR_INLINE bool to(const double& from, int64_t& to)
  947. {
  948. return convert_to(from, to);
  949. }
  950. static RTTR_INLINE bool to(const double& from, uint8_t& to)
  951. {
  952. return convert_to(from, to);
  953. }
  954. static RTTR_INLINE bool to(const double& from, uint16_t& to)
  955. {
  956. return convert_to(from, to);
  957. }
  958. static RTTR_INLINE bool to(const double& from, uint32_t& to)
  959. {
  960. return convert_to(from, to);
  961. }
  962. static RTTR_INLINE bool to(const double& from, uint64_t& to)
  963. {
  964. return convert_to(from, to);
  965. }
  966. static RTTR_INLINE bool to(const double& from, float& to)
  967. {
  968. RTTR_CONSTEXPR_OR_CONST double float_min = -1 * (std::numeric_limits<float>::max)();
  969. RTTR_CONSTEXPR_OR_CONST double float_max = (std::numeric_limits<float>::max)();
  970. if (from < float_min || from > float_max)
  971. return false;
  972. to = static_cast<float>(from);
  973. return true;
  974. }
  975. static RTTR_INLINE bool to(const double& from, double& to)
  976. {
  977. to = from;
  978. return true;
  979. }
  980. static RTTR_INLINE bool to(const double& from, std::string& to)
  981. {
  982. return convert_to(from, to);
  983. }
  984. static RTTR_INLINE bool to_enum(const double& from, argument& to)
  985. {
  986. return to_enumeration(from, to);
  987. }
  988. };
  989. /////////////////////////////////////////////////////////////////////////////////////////
  990. template<>
  991. struct RTTR_API convert_from<std::string>
  992. {
  993. static RTTR_INLINE bool to(const std::string& from, bool& to)
  994. {
  995. bool ok;
  996. to = string_to_bool(from, &ok);
  997. return ok;
  998. }
  999. static RTTR_INLINE bool to(const std::string& from, char& to)
  1000. {
  1001. const auto& val = from;
  1002. if (val.empty())
  1003. to ='\0';
  1004. else
  1005. to = val[0];
  1006. return true;
  1007. }
  1008. static RTTR_INLINE bool to(const std::string& from, int8_t& to)
  1009. {
  1010. bool ok;
  1011. int val = string_to_int(from, &ok);
  1012. if (!ok)
  1013. return false;
  1014. return convert_to(val, to);
  1015. }
  1016. static RTTR_INLINE bool to(const std::string& from, int16_t& to)
  1017. {
  1018. bool ok;
  1019. int val = string_to_int(from, &ok);
  1020. if (!ok)
  1021. return false;
  1022. return convert_to(val, to);
  1023. }
  1024. static RTTR_INLINE bool to(const std::string& from, int32_t& to)
  1025. {
  1026. bool ok;
  1027. to = string_to_int(from, &ok);
  1028. return ok;
  1029. }
  1030. static RTTR_INLINE bool to(const std::string& from, int64_t& to)
  1031. {
  1032. bool ok;
  1033. to = string_to_long_long(from, &ok);
  1034. return ok;
  1035. }
  1036. static RTTR_INLINE bool to(const std::string& from, uint8_t& to)
  1037. {
  1038. bool ok;
  1039. unsigned int val = string_to_int(from, &ok);
  1040. if (!ok)
  1041. return false;
  1042. return convert_to(val, to);
  1043. }
  1044. static RTTR_INLINE bool to(const std::string& from, uint16_t& to)
  1045. {
  1046. bool ok;
  1047. unsigned int val = string_to_int(from, &ok);
  1048. if (!ok)
  1049. return false;
  1050. return convert_to(val, to);
  1051. }
  1052. static RTTR_INLINE bool to(const std::string& from, uint32_t& to)
  1053. {
  1054. bool ok;
  1055. const auto val = string_to_ulong(from, &ok);
  1056. if (!ok)
  1057. return false;
  1058. return convert_to(val, to);
  1059. }
  1060. static RTTR_INLINE bool to(const std::string& from, uint64_t& to)
  1061. {
  1062. bool ok;
  1063. const auto val = string_to_ulong_long(from, &ok);
  1064. if (!ok)
  1065. return false;
  1066. return convert_to(val, to);
  1067. }
  1068. static RTTR_INLINE bool to(const std::string& from, float& to)
  1069. {
  1070. bool ok;
  1071. to = string_to_float(from, &ok);
  1072. return ok;
  1073. }
  1074. static RTTR_INLINE bool to(const std::string& from, double& to)
  1075. {
  1076. bool ok;
  1077. to = string_to_double(from, &ok);
  1078. return ok;
  1079. }
  1080. static RTTR_INLINE bool to(const std::string& from, std::string& to)
  1081. {
  1082. to = from;
  1083. return true;
  1084. }
  1085. static RTTR_INLINE bool to_enum(const std::string& from, argument& to)
  1086. {
  1087. return to_enumeration(string_view(from), to);
  1088. }
  1089. };
  1090. /////////////////////////////////////////////////////////////////////////////////////////
  1091. // MSVC generates following warning: 'warning C4800: 'const enum_bool' : forcing value to bool 'true' or 'false' (performance warning)'
  1092. // For unknown reason the MSVC compiler is too dump to recognize that I can safely convert an enumeration
  1093. // with underlying type bool, to type bool (thats no int to bool conversion!)
  1094. // so we disable the warning for enum conversions:
  1095. #if RTTR_COMPILER == RTTR_COMPILER_MSVC
  1096. #pragma warning(push)
  1097. #pragma warning(disable:4800)
  1098. #endif
  1099. template<typename T>
  1100. struct convert_from_enum
  1101. {
  1102. template<typename T_>
  1103. using enum_type_t = typename std::underlying_type<T_>::type;
  1104. static RTTR_INLINE enum_type_t<T> get_underlying_value(const T& from)
  1105. {
  1106. return static_cast<enum_type_t<T>>(from);
  1107. }
  1108. template<typename T1>
  1109. static RTTR_INLINE
  1110. enable_if_t<!std::is_same<bool, enum_type_t<T1> >::value, bool>
  1111. to(const T1& from, bool& to)
  1112. {
  1113. const auto value = get_underlying_value(from);
  1114. if (value == 0)
  1115. {
  1116. to = false;
  1117. return true;
  1118. }
  1119. else if (value == 1)
  1120. {
  1121. to = true;
  1122. return true;
  1123. }
  1124. else
  1125. {
  1126. return false;
  1127. }
  1128. }
  1129. template<typename T1>
  1130. static RTTR_INLINE
  1131. enable_if_t<std::is_same<bool, enum_type_t<T1> >::value, bool>
  1132. to(const T1& from, bool& to)
  1133. {
  1134. // for unknown reason MSVC will here scream a warning 'C4800'...
  1135. to = static_cast<bool>(from);
  1136. return true;
  1137. }
  1138. static RTTR_INLINE bool to(const T& from, char& to)
  1139. {
  1140. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1141. }
  1142. static RTTR_INLINE bool to(const T& from, int8_t& to)
  1143. {
  1144. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1145. }
  1146. static RTTR_INLINE bool to(const T& from, int16_t& to)
  1147. {
  1148. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1149. }
  1150. static RTTR_INLINE bool to(const T& from, int32_t& to)
  1151. {
  1152. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1153. }
  1154. static RTTR_INLINE bool to(const T& from, int64_t& to)
  1155. {
  1156. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1157. }
  1158. static RTTR_INLINE bool to(const T& from, uint8_t& to)
  1159. {
  1160. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1161. }
  1162. static RTTR_INLINE bool to(const T& from, uint16_t& to)
  1163. {
  1164. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1165. }
  1166. static RTTR_INLINE bool to(const T& from, uint32_t& to)
  1167. {
  1168. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1169. }
  1170. static RTTR_INLINE bool to(const T& from, uint64_t& to)
  1171. {
  1172. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1173. }
  1174. static RTTR_INLINE bool to(const T& from, float& to)
  1175. {
  1176. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1177. }
  1178. static RTTR_INLINE bool to(const T& from, double& to)
  1179. {
  1180. return convert_from<enum_type_t<T>>::to(get_underlying_value(from), to);
  1181. }
  1182. static RTTR_INLINE bool to(const T& from, std::string& to)
  1183. {
  1184. to = get_enumeration_name(from).to_string();
  1185. return (to.empty() == false);
  1186. }
  1187. static RTTR_INLINE bool to_enum(const T& from, argument& to)
  1188. {
  1189. return false;
  1190. }
  1191. };
  1192. /////////////////////////////////////////////////////////////////////////////////////////
  1193. #if RTTR_COMPILER == RTTR_COMPILER_MSVC
  1194. // restore warning level
  1195. #pragma warning(pop)
  1196. #endif
  1197. /////////////////////////////////////////////////////////////////////////////////////////
  1198. } // end namespace detail
  1199. } // end namespace rttr
  1200. #endif // RTTR_VARIANT_DATA_CONVERTER_H_