PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/cxxtools-2.1.1/src/convert.cpp

#
C++ | 702 lines | 476 code | 184 blank | 42 comment | 64 complexity | 7701b15cc70bd97754cbe036dd960181 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /*
  2. * Copyright (C) 2011 Tommi Maekitalo
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * As a special exception, you may use this file as part of a free
  10. * software library without restriction. Specifically, if other files
  11. * instantiate templates or use macros or inline functions from this
  12. * file, or you compile this file and link it with other files to
  13. * produce an executable, this file does not by itself cause the
  14. * resulting executable to be covered by the GNU General Public
  15. * License. This exception does not however invalidate any other
  16. * reasons why the executable file might be covered by the GNU Library
  17. * General Public License.
  18. *
  19. * This library is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22. * Lesser General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU Lesser General Public
  25. * License along with this library; if not, write to the Free Software
  26. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  27. */
  28. #include <cxxtools/convert.h>
  29. #include <iomanip>
  30. #include <limits>
  31. #include <cctype>
  32. namespace cxxtools
  33. {
  34. template <typename IterT>
  35. void _skipws(IterT& it, IterT end)
  36. {
  37. while (it != end && isspace(*it))
  38. ++it;
  39. }
  40. template<typename T>
  41. class nullterm_array_iterator : public std::iterator<std::input_iterator_tag, T>
  42. {
  43. public:
  44. nullterm_array_iterator()
  45. : _ptr(0)
  46. { }
  47. explicit nullterm_array_iterator(const T* ptr)
  48. : _ptr(ptr)
  49. {
  50. if(*_ptr == '\0')
  51. _ptr = 0;
  52. }
  53. nullterm_array_iterator<T>& operator=(const nullterm_array_iterator<T>& it)
  54. {
  55. _ptr = it._ptr;
  56. return *this;
  57. }
  58. bool operator==(const nullterm_array_iterator<T>& it) const
  59. {
  60. return _ptr == it._ptr;
  61. }
  62. bool operator!=(const nullterm_array_iterator<T>& it) const
  63. {
  64. return _ptr != it._ptr;
  65. }
  66. const T& operator*() const
  67. {
  68. return *_ptr;
  69. }
  70. nullterm_array_iterator<T>& operator++()
  71. {
  72. if(*++_ptr == '\0')
  73. _ptr = 0;
  74. return *this;
  75. }
  76. nullterm_array_iterator<T> operator++(int)
  77. {
  78. if(*++_ptr == '\0')
  79. _ptr = 0;
  80. return *this;
  81. }
  82. private:
  83. const T* _ptr;
  84. };
  85. template <typename T>
  86. void convertInt(T& n, const String& str, const char* typeto)
  87. {
  88. bool ok = false;
  89. String::const_iterator r = getInt( str.begin(), str.end(), ok, n );
  90. if (ok)
  91. _skipws(r, str.end());
  92. if( r != str.end() || ! ok )
  93. ConversionError::doThrow(typeto, "String", str.narrow().c_str());
  94. }
  95. template <typename T>
  96. void convertInt(T& n, const std::string& str, const char* typeto)
  97. {
  98. bool ok = false;
  99. std::string::const_iterator r = getInt( str.begin(), str.end(), ok, n );
  100. if (ok)
  101. _skipws(r, str.end());
  102. if( r != str.end() || ! ok )
  103. ConversionError::doThrow(typeto, "string", str.c_str());
  104. }
  105. template <typename T>
  106. void convertInt(T& n, const char* str, const char* typeto)
  107. {
  108. bool ok = false;
  109. nullterm_array_iterator<char> it(str);
  110. nullterm_array_iterator<char> end;
  111. it = getInt( it, end, ok, n );
  112. if (ok)
  113. _skipws(it, end);
  114. if( it != end || ! ok )
  115. ConversionError::doThrow(typeto, "char*");
  116. }
  117. template <typename T>
  118. void convertFloat(T& n, const String& str, const char* typeto)
  119. {
  120. bool ok = false;
  121. String::const_iterator r = getFloat(str.begin(), str.end(), ok, n);
  122. if (ok)
  123. _skipws(r, str.end());
  124. if(r != str.end() || ! ok)
  125. ConversionError::doThrow(typeto, "String", str.narrow().c_str());
  126. }
  127. template <typename T>
  128. void convertFloat(T& n, const std::string& str, const char* typeto)
  129. {
  130. bool ok = false;
  131. std::string::const_iterator r = getFloat(str.begin(), str.end(), ok, n);
  132. if (ok)
  133. _skipws(r, str.end());
  134. if(r != str.end() || ! ok)
  135. ConversionError::doThrow(typeto, "string", str.c_str());
  136. }
  137. template <typename T>
  138. void convertFloat(T& n, const char* str, const char* typeto)
  139. {
  140. bool ok = false;
  141. nullterm_array_iterator<char> it(str);
  142. nullterm_array_iterator<char> end;
  143. it = getFloat( it, end, ok, n );
  144. if (ok)
  145. _skipws(it, end);
  146. if( it != end || ! ok )
  147. ConversionError::doThrow(typeto, "char*", str);
  148. }
  149. //
  150. // Conversions to cxxtools::String
  151. //
  152. void convert(String& s, const std::string& value)
  153. {
  154. s = String::widen(value);
  155. }
  156. void convert(String& str, bool value)
  157. {
  158. static const wchar_t* trueValue = L"true";
  159. static const wchar_t* falseValue = L"false";
  160. str = value ? trueValue : falseValue;
  161. }
  162. void convert(String& str, char value)
  163. {
  164. str = String( 1, Char(value) );
  165. }
  166. void convert(String& str, unsigned char value)
  167. {
  168. str.clear();
  169. putInt(std::back_inserter(str), value);
  170. }
  171. void convert(String& str, signed char value)
  172. {
  173. str.clear();
  174. putInt(std::back_inserter(str), value);
  175. }
  176. void convert(String& str, short value)
  177. {
  178. str.clear();
  179. putInt(std::back_inserter(str), value);
  180. }
  181. void convert(String& str, unsigned short value)
  182. {
  183. str.clear();
  184. putInt(std::back_inserter(str), value);
  185. }
  186. void convert(String& str, int value)
  187. {
  188. str.clear();
  189. putInt(std::back_inserter(str), value);
  190. }
  191. void convert(String& str, unsigned int value)
  192. {
  193. str.clear();
  194. putInt(std::back_inserter(str), value);
  195. }
  196. void convert(String& str, long value)
  197. {
  198. str.clear();
  199. putInt(std::back_inserter(str), value);
  200. }
  201. void convert(String& str, unsigned long value)
  202. {
  203. str.clear();
  204. putInt(std::back_inserter(str), value);
  205. }
  206. void convert(String& str, float value)
  207. {
  208. str.clear();
  209. putFloat(std::back_inserter(str), value);
  210. }
  211. void convert(String& str, double value)
  212. {
  213. str.clear();
  214. putFloat(std::back_inserter(str), value);
  215. }
  216. void convert(String& str, long double value)
  217. {
  218. str.clear();
  219. putFloat(std::back_inserter(str), value);
  220. }
  221. //
  222. // Conversions from cxxtools::String
  223. //
  224. void convert(bool& n, const String& str)
  225. {
  226. if (str == L"true" || str == L"1")
  227. n = true;
  228. else if (str == L"false" || str == L"0")
  229. n = false;
  230. else
  231. ConversionError::doThrow("bool", "String", str.narrow().c_str());
  232. }
  233. void convert(char& c, const String& str)
  234. {
  235. if ( str.empty() )
  236. ConversionError::doThrow("char", "String");
  237. int n = str[0];
  238. c = n;
  239. }
  240. void convert(unsigned char& n, const String& str)
  241. {
  242. convertInt(n, str, "unsigned char");
  243. }
  244. void convert(signed char& n, const String& str)
  245. {
  246. convertInt(n, str, "signed char");
  247. }
  248. void convert(short& n, const String& str)
  249. {
  250. convertInt(n, str, "short");
  251. }
  252. void convert(unsigned short& n, const String& str)
  253. {
  254. convertInt(n, str, "unsigned short");
  255. }
  256. void convert(int& n, const String& str)
  257. {
  258. convertInt(n, str, "int");
  259. }
  260. void convert(unsigned int& n, const String& str)
  261. {
  262. convertInt(n, str, "unsigned int");
  263. }
  264. void convert(long& n, const String& str)
  265. {
  266. convertInt(n, str, "long");
  267. }
  268. void convert(unsigned long& n, const String& str)
  269. {
  270. convertInt(n, str, "unsigned long");
  271. }
  272. #ifdef HAVE_LONG_LONG
  273. void convert(long long& n, const String& str)
  274. {
  275. convertInt(n, str, "long long");
  276. }
  277. #endif
  278. #ifdef HAVE_UNSIGNED_LONG_LONG
  279. void convert(unsigned long long& n, const String& str)
  280. {
  281. convertInt(n, str, "unsigned long long");
  282. }
  283. #endif
  284. void convert(float& n, const String& str)
  285. {
  286. convertFloat(n, str, "float");
  287. }
  288. void convert(double& n, const String& str)
  289. {
  290. convertFloat(n, str, "double");
  291. }
  292. void convert(long double& n, const String& str)
  293. {
  294. convertFloat(n, str, "long double");
  295. }
  296. //
  297. // Conversions to std::string
  298. //
  299. void convert(std::string& s, const String& str)
  300. {
  301. s = str.narrow();
  302. }
  303. void convert(std::string& str, bool value)
  304. {
  305. static const char* trueValue = "true";
  306. static const char* falseValue = "false";
  307. str = value ? trueValue : falseValue;
  308. }
  309. void convert(std::string& str, char value)
  310. {
  311. str.clear();
  312. str += value;
  313. }
  314. void convert(std::string& str, signed char value)
  315. {
  316. str.clear();
  317. putInt(std::back_inserter(str), value);
  318. }
  319. void convert(std::string& str, unsigned char value)
  320. {
  321. str.clear();
  322. putInt(std::back_inserter(str), value);
  323. }
  324. void convert(std::string& str, short value)
  325. {
  326. str.clear();
  327. putInt(std::back_inserter(str), value);
  328. }
  329. void convert(std::string& str, unsigned short value)
  330. {
  331. str.clear();
  332. putInt(std::back_inserter(str), value);
  333. }
  334. void convert(std::string& str, int value)
  335. {
  336. str.clear();
  337. putInt(std::back_inserter(str), value);
  338. }
  339. void convert(std::string& str, unsigned int value)
  340. {
  341. str.clear();
  342. putInt(std::back_inserter(str), value);
  343. }
  344. void convert(std::string& str, long value)
  345. {
  346. str.clear();
  347. putInt(std::back_inserter(str), value);
  348. }
  349. void convert(std::string& str, unsigned long value)
  350. {
  351. str.clear();
  352. putInt(std::back_inserter(str), value);
  353. }
  354. void convert(std::string& str, float value)
  355. {
  356. str.clear();
  357. putFloat(std::back_inserter(str), value);
  358. }
  359. void convert(std::string& str, double value)
  360. {
  361. str.clear();
  362. putFloat(std::back_inserter(str), value);
  363. }
  364. void convert(std::string& str, long double value)
  365. {
  366. str.clear();
  367. putFloat(std::back_inserter(str), value);
  368. }
  369. //
  370. // Conversions from std::string
  371. //
  372. void convert(bool& n, const std::string& str)
  373. {
  374. if (str == "true" || str == "1")
  375. n = true;
  376. else if (str == "false" || str == "0")
  377. n = false;
  378. else
  379. ConversionError::doThrow("bool", "string", str.c_str());
  380. }
  381. void convert(char& c, const std::string& str)
  382. {
  383. if ( str.empty() )
  384. ConversionError::doThrow("char", "string");
  385. int n = str[0];
  386. c = n;
  387. }
  388. void convert(signed char& n, const std::string& str)
  389. {
  390. convertInt(n, str, "signed char");
  391. }
  392. void convert(unsigned char& n, const std::string& str)
  393. {
  394. convertInt(n, str, "unsigned char");
  395. }
  396. void convert(short& n, const std::string& str)
  397. {
  398. convertInt(n, str, "short");
  399. }
  400. void convert(unsigned short& n, const std::string& str)
  401. {
  402. convertInt(n, str, "unsigned short");
  403. }
  404. void convert(int& n, const std::string& str)
  405. {
  406. convertInt(n, str, "int");
  407. }
  408. void convert(unsigned int& n, const std::string& str)
  409. {
  410. convertInt(n, str, "unsigned int");
  411. }
  412. void convert(long& n, const std::string& str)
  413. {
  414. convertInt(n, str, "long");
  415. }
  416. void convert(unsigned long& n, const std::string& str)
  417. {
  418. convertInt(n, str, "unsigned long");
  419. }
  420. #ifdef HAVE_LONG_LONG
  421. void convert(long long& n, const std::string& str)
  422. {
  423. convertInt(n, str, "long long");
  424. }
  425. #endif
  426. #ifdef HAVE_UNSIGNED_LONG_LONG
  427. void convert(unsigned long long& n, const std::string& str)
  428. {
  429. convertInt(n, str, "unsigned long long");
  430. }
  431. #endif
  432. void convert(float& n, const std::string& str)
  433. {
  434. convertFloat(n, str, "float");
  435. }
  436. void convert(double& n, const std::string& str)
  437. {
  438. convertFloat(n, str, "double");
  439. }
  440. void convert(long double& n, const std::string& str)
  441. {
  442. convertFloat(n, str, "long double");
  443. }
  444. //
  445. // Conversions from const char*
  446. //
  447. void convert(bool& n, const char* str)
  448. {
  449. if (std::strcmp(str, "true") == 0 || std::strcmp(str, "1") == 0)
  450. n = true;
  451. else if (std::strcmp(str, "false") || std::strcmp(str, "0"))
  452. n = false;
  453. else
  454. ConversionError::doThrow("bool", "char*", str);
  455. }
  456. void convert(char& c, const char* str)
  457. {
  458. if ( *str == '\0' )
  459. ConversionError::doThrow("char", "char*");
  460. c = str[0];
  461. }
  462. void convert(signed char& n, const char* str)
  463. {
  464. convertInt(n, str, "signed char");
  465. }
  466. void convert(unsigned char& n, const char* str)
  467. {
  468. convertInt(n, str, "unsigned char");
  469. }
  470. void convert(short& n, const char* str)
  471. {
  472. convertInt(n, str, "short");
  473. }
  474. void convert(unsigned short& n, const char* str)
  475. {
  476. convertInt(n, str, "unsigned short");
  477. }
  478. void convert(int& n, const char* str)
  479. {
  480. convertInt(n, str, "int");
  481. }
  482. void convert(unsigned int& n, const char* str)
  483. {
  484. convertInt(n, str, "unsigned int");
  485. }
  486. void convert(long& n, const char* str)
  487. {
  488. convertInt(n, str, "long");
  489. }
  490. void convert(unsigned long& n, const char* str)
  491. {
  492. convertInt(n, str, "unsigned long");
  493. }
  494. #ifdef HAVE_LONG_LONG
  495. void convert(long long& n, const char* str)
  496. {
  497. convertInt(n, str, "long long");
  498. }
  499. #endif
  500. #ifdef HAVE_UNSIGNED_LONG_LONG
  501. void convert(unsigned long long& n, const char* str)
  502. {
  503. convertInt(n, str, "unsigned long long");
  504. }
  505. #endif
  506. void convert(float& n, const char* str)
  507. {
  508. convertFloat(n, str, "float");
  509. }
  510. void convert(double& n, const char* str)
  511. {
  512. convertFloat(n, str, "double");
  513. }
  514. void convert(long double& n, const char* str)
  515. {
  516. convertFloat(n, str, "long double");
  517. }
  518. }