std_conversion_functions.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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. #include "rttr/detail/conversion/std_conversion_functions.h"
  28. #include "rttr/detail/conversion/number_conversion.h"
  29. #include <sstream>
  30. #include <locale>
  31. #include <limits>
  32. #include <algorithm>
  33. #include <climits>
  34. #include <iomanip>
  35. namespace rttr
  36. {
  37. namespace detail
  38. {
  39. /////////////////////////////////////////////////////////////////////////////////////////
  40. template<typename T>
  41. std::string to_string_impl(T value, bool* ok)
  42. {
  43. try
  44. {
  45. std::string text = std::to_string(value);
  46. if (ok)
  47. *ok = true;
  48. return text;
  49. }
  50. catch (...)
  51. {
  52. if (ok)
  53. *ok = false;
  54. return std::string();
  55. }
  56. }
  57. /////////////////////////////////////////////////////////////////////////////////////////
  58. std::string to_string(int value, bool* ok)
  59. {
  60. return to_string_impl(value, ok);
  61. }
  62. /////////////////////////////////////////////////////////////////////////////////////////
  63. std::string to_string(long value, bool* ok)
  64. {
  65. return to_string_impl(value, ok);
  66. }
  67. /////////////////////////////////////////////////////////////////////////////////////////
  68. std::string to_string(long long value, bool* ok)
  69. {
  70. return to_string_impl(value, ok);
  71. }
  72. /////////////////////////////////////////////////////////////////////////////////////////
  73. std::string to_string(unsigned value, bool* ok)
  74. {
  75. return to_string_impl(value, ok);
  76. }
  77. /////////////////////////////////////////////////////////////////////////////////////////
  78. std::string to_string(unsigned long value, bool* ok)
  79. {
  80. return to_string_impl(value, ok);
  81. }
  82. /////////////////////////////////////////////////////////////////////////////////////////
  83. std::string to_string(unsigned long long value, bool* ok)
  84. {
  85. return to_string_impl(value, ok);
  86. }
  87. /////////////////////////////////////////////////////////////////////////////////////////
  88. std::string to_string(float value, bool* ok)
  89. {
  90. try
  91. {
  92. std::stringstream ss;
  93. ss << std::setprecision(std::numeric_limits<float>::digits10) << value;
  94. if (ok)
  95. *ok = true;
  96. return ss.str();
  97. }
  98. catch (...)
  99. {
  100. if (ok)
  101. *ok = false;
  102. return std::string();
  103. }
  104. }
  105. /////////////////////////////////////////////////////////////////////////////////////////
  106. std::string to_string(double value, bool* ok)
  107. {
  108. try
  109. {
  110. std::stringstream ss;
  111. ss << std::setprecision(std::numeric_limits<double>::digits10) << value;
  112. if (ok)
  113. *ok = true;
  114. return ss.str();
  115. }
  116. catch (...)
  117. {
  118. if (ok)
  119. *ok = false;
  120. return std::string();
  121. }
  122. }
  123. /////////////////////////////////////////////////////////////////////////////////////////
  124. /////////////////////////////////////////////////////////////////////////////////////////
  125. /////////////////////////////////////////////////////////////////////////////////////////
  126. bool string_to_bool(std::string text, bool* ok)
  127. {
  128. std::transform(text.begin(), text.end(), text.begin(), [](char ch) { return std::tolower(ch, std::locale::classic()); });
  129. text.erase( std::remove_if( text.begin(), text.end(), [](char ch) { return std::isspace(ch, std::locale::classic() ); } ), text.end() );
  130. if (text == "false" || text == "0" || text.empty())
  131. {
  132. if (ok)
  133. *ok = true;
  134. return false;
  135. }
  136. if (ok)
  137. *ok = true;
  138. return true;
  139. }
  140. /////////////////////////////////////////////////////////////////////////////////////////
  141. int string_to_int(const std::string& source, bool* ok)
  142. {
  143. try
  144. {
  145. std::size_t pos = 0;
  146. const int value = std::stoi(source, &pos);
  147. if (pos == source.length())
  148. {
  149. if (ok)
  150. *ok = true;
  151. return value;
  152. }
  153. }
  154. catch (...)
  155. {
  156. if (ok)
  157. *ok = false;
  158. return 0;
  159. }
  160. if (ok)
  161. *ok = false;
  162. return 0;
  163. }
  164. /////////////////////////////////////////////////////////////////////////////////////////
  165. unsigned long string_to_ulong(const std::string& source, bool* ok)
  166. {
  167. try
  168. {
  169. std::size_t pos = 0;
  170. const long long value = std::stoll(source, &pos);
  171. unsigned long result = 0;
  172. if (pos == source.length() && convert_to(value, result))
  173. {
  174. if (ok)
  175. *ok = true;
  176. return result;
  177. }
  178. }
  179. catch (...)
  180. {
  181. if (ok)
  182. *ok = false;
  183. return 0;
  184. }
  185. if (ok)
  186. *ok = false;
  187. return 0;
  188. }
  189. /////////////////////////////////////////////////////////////////////////////////////////
  190. long long string_to_long_long(const std::string& source, bool* ok)
  191. {
  192. try
  193. {
  194. std::size_t pos = 0;
  195. const long long value = std::stoll(source, &pos);
  196. if (pos == source.length())
  197. {
  198. if (ok)
  199. *ok = true;
  200. return value;
  201. }
  202. }
  203. catch (...)
  204. {
  205. if (ok)
  206. *ok = false;
  207. return 0;
  208. }
  209. if (ok)
  210. *ok = false;
  211. return 0;
  212. }
  213. /////////////////////////////////////////////////////////////////////////////////////////
  214. unsigned long long string_to_ulong_long(const std::string& source, bool* ok)
  215. {
  216. try
  217. {
  218. std::size_t pos = 0;
  219. const auto itr = std::find_if(source.begin(), source.end(), [](char c){ return !std::isdigit(c, std::locale()); });
  220. if (itr == source.end())
  221. {
  222. const unsigned long long value = std::stoull(source, &pos);
  223. if (pos == source.length())
  224. {
  225. if (ok)
  226. *ok = true;
  227. return value;
  228. }
  229. }
  230. }
  231. catch (...)
  232. {
  233. if (ok)
  234. *ok = false;
  235. return 0;
  236. }
  237. if (ok)
  238. *ok = false;
  239. return 0;
  240. }
  241. /////////////////////////////////////////////////////////////////////////////////////////
  242. float string_to_float(const std::string& source, bool* ok)
  243. {
  244. try
  245. {
  246. std::size_t pos = 0;
  247. const float value = std::stof(source, &pos);
  248. if (pos == source.length())
  249. {
  250. if (ok)
  251. *ok = true;
  252. return value;
  253. }
  254. }
  255. catch (...)
  256. {
  257. if (ok)
  258. *ok = false;
  259. return 0;
  260. }
  261. if (ok)
  262. *ok = false;
  263. return 0;
  264. }
  265. /////////////////////////////////////////////////////////////////////////////////////////
  266. double string_to_double(const std::string& source, bool* ok)
  267. {
  268. try
  269. {
  270. std::size_t pos = 0;
  271. const double value = std::stod(source, &pos);
  272. if (pos == source.length())
  273. {
  274. if (ok)
  275. *ok = true;
  276. return value;
  277. }
  278. }
  279. catch (...)
  280. {
  281. if (ok)
  282. *ok = false;
  283. return 0;
  284. }
  285. if (ok)
  286. *ok = false;
  287. return 0;
  288. }
  289. /////////////////////////////////////////////////////////////////////////////////////////
  290. } // end namespace detail
  291. } // end namespace rttr