string.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. //===------------------------- string.cpp ---------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "string"
  10. #include "cstdlib"
  11. #include "cwchar"
  12. #include "cerrno"
  13. #include "limits"
  14. #include "stdexcept"
  15. #ifdef _LIBCPP_MSVCRT
  16. #include "support/win32/support.h"
  17. #endif // _LIBCPP_MSVCRT
  18. #include <stdio.h>
  19. _LIBCPP_BEGIN_NAMESPACE_STD
  20. template class __basic_string_common<true>;
  21. template class basic_string<char>;
  22. template class basic_string<wchar_t>;
  23. template
  24. string
  25. operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
  26. namespace
  27. {
  28. template<typename T>
  29. inline
  30. void throw_helper( const string& msg )
  31. {
  32. #ifndef _LIBCPP_NO_EXCEPTIONS
  33. throw T( msg );
  34. #else
  35. #if !defined(_LIBCPP_SGX_NO_IOSTREAMS)
  36. fprintf(stderr, "%s\n", msg.c_str());
  37. #endif // !defined(_LIBCPP_SGX_NO_IOSTREAMS)
  38. abort();
  39. #endif
  40. }
  41. inline
  42. void throw_from_string_out_of_range( const string& func )
  43. {
  44. throw_helper<out_of_range>(func + ": out of range");
  45. }
  46. inline
  47. void throw_from_string_invalid_arg( const string& func )
  48. {
  49. throw_helper<invalid_argument>(func + ": no conversion");
  50. }
  51. // as_integer
  52. template<typename V, typename S, typename F>
  53. inline
  54. V
  55. as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
  56. {
  57. typename S::value_type* ptr = nullptr;
  58. const typename S::value_type* const p = str.c_str();
  59. typename remove_reference<decltype(errno)>::type errno_save = errno;
  60. errno = 0;
  61. V r = f(p, &ptr, base);
  62. swap(errno, errno_save);
  63. if (errno_save == ERANGE)
  64. throw_from_string_out_of_range(func);
  65. if (ptr == p)
  66. throw_from_string_invalid_arg(func);
  67. if (idx)
  68. *idx = static_cast<size_t>(ptr - p);
  69. return r;
  70. }
  71. template<typename V, typename S>
  72. inline
  73. V
  74. as_integer(const string& func, const S& s, size_t* idx, int base);
  75. // string
  76. template<>
  77. inline
  78. int
  79. as_integer(const string& func, const string& s, size_t* idx, int base )
  80. {
  81. // Use long as no Standard string to integer exists.
  82. long r = as_integer_helper<long>( func, s, idx, base, strtol );
  83. if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
  84. throw_from_string_out_of_range(func);
  85. return static_cast<int>(r);
  86. }
  87. template<>
  88. inline
  89. long
  90. as_integer(const string& func, const string& s, size_t* idx, int base )
  91. {
  92. return as_integer_helper<long>( func, s, idx, base, strtol );
  93. }
  94. template<>
  95. inline
  96. unsigned long
  97. as_integer( const string& func, const string& s, size_t* idx, int base )
  98. {
  99. return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
  100. }
  101. template<>
  102. inline
  103. long long
  104. as_integer( const string& func, const string& s, size_t* idx, int base )
  105. {
  106. return as_integer_helper<long long>( func, s, idx, base, strtoll );
  107. }
  108. template<>
  109. inline
  110. unsigned long long
  111. as_integer( const string& func, const string& s, size_t* idx, int base )
  112. {
  113. return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
  114. }
  115. // wstring
  116. // Implement support for wcstoxxx api in wchar.h
  117. #if !defined(_LIBCPP_SGX_CONFIG)
  118. template<>
  119. inline
  120. int
  121. as_integer( const string& func, const wstring& s, size_t* idx, int base )
  122. {
  123. // Use long as no Stantard string to integer exists.
  124. long r = as_integer_helper<long>( func, s, idx, base, wcstol );
  125. if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
  126. throw_from_string_out_of_range(func);
  127. return static_cast<int>(r);
  128. }
  129. template<>
  130. inline
  131. long
  132. as_integer( const string& func, const wstring& s, size_t* idx, int base )
  133. {
  134. return as_integer_helper<long>( func, s, idx, base, wcstol );
  135. }
  136. template<>
  137. inline
  138. unsigned long
  139. as_integer( const string& func, const wstring& s, size_t* idx, int base )
  140. {
  141. return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
  142. }
  143. template<>
  144. inline
  145. long long
  146. as_integer( const string& func, const wstring& s, size_t* idx, int base )
  147. {
  148. return as_integer_helper<long long>( func, s, idx, base, wcstoll );
  149. }
  150. template<>
  151. inline
  152. unsigned long long
  153. as_integer( const string& func, const wstring& s, size_t* idx, int base )
  154. {
  155. return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
  156. }
  157. #endif // !defined(_LIBCPP_SGX_CONFIG)
  158. // as_float
  159. template<typename V, typename S, typename F>
  160. inline
  161. V
  162. as_float_helper(const string& func, const S& str, size_t* idx, F f )
  163. {
  164. typename S::value_type* ptr = nullptr;
  165. const typename S::value_type* const p = str.c_str();
  166. typename remove_reference<decltype(errno)>::type errno_save = errno;
  167. errno = 0;
  168. V r = f(p, &ptr);
  169. swap(errno, errno_save);
  170. if (errno_save == ERANGE)
  171. throw_from_string_out_of_range(func);
  172. if (ptr == p)
  173. throw_from_string_invalid_arg(func);
  174. if (idx)
  175. *idx = static_cast<size_t>(ptr - p);
  176. return r;
  177. }
  178. template<typename V, typename S>
  179. inline
  180. V as_float( const string& func, const S& s, size_t* idx = nullptr );
  181. template<>
  182. inline
  183. float
  184. as_float( const string& func, const string& s, size_t* idx )
  185. {
  186. return as_float_helper<float>( func, s, idx, strtof );
  187. }
  188. template<>
  189. inline
  190. double
  191. as_float(const string& func, const string& s, size_t* idx )
  192. {
  193. return as_float_helper<double>( func, s, idx, strtod );
  194. }
  195. template<>
  196. inline
  197. long double
  198. as_float( const string& func, const string& s, size_t* idx )
  199. {
  200. return as_float_helper<long double>( func, s, idx, strtold );
  201. }
  202. // Implement support for wcstoxxx api in wchar.h
  203. #if !defined(_LIBCPP_SGX_CONFIG)
  204. template<>
  205. inline
  206. float
  207. as_float( const string& func, const wstring& s, size_t* idx )
  208. {
  209. return as_float_helper<float>( func, s, idx, wcstof );
  210. }
  211. template<>
  212. inline
  213. double
  214. as_float( const string& func, const wstring& s, size_t* idx )
  215. {
  216. return as_float_helper<double>( func, s, idx, wcstod );
  217. }
  218. template<>
  219. inline
  220. long double
  221. as_float( const string& func, const wstring& s, size_t* idx )
  222. {
  223. return as_float_helper<long double>( func, s, idx, wcstold );
  224. }
  225. #endif // !defined(_LIBCPP_SGX_CONFIG)
  226. } // unnamed namespace
  227. int
  228. stoi(const string& str, size_t* idx, int base)
  229. {
  230. return as_integer<int>( "stoi", str, idx, base );
  231. }
  232. // Implement support for wcstoxxx api in wchar.h
  233. #if !defined(_LIBCPP_SGX_CONFIG)
  234. int
  235. stoi(const wstring& str, size_t* idx, int base)
  236. {
  237. return as_integer<int>( "stoi", str, idx, base );
  238. }
  239. #endif // !defined(_LIBCPP_SGX_CONFIG)
  240. long
  241. stol(const string& str, size_t* idx, int base)
  242. {
  243. return as_integer<long>( "stol", str, idx, base );
  244. }
  245. // Implement support for wcstoxxx api in wchar.h
  246. #if !defined(_LIBCPP_SGX_CONFIG)
  247. long
  248. stol(const wstring& str, size_t* idx, int base)
  249. {
  250. return as_integer<long>( "stol", str, idx, base );
  251. }
  252. #endif // !defined(_LIBCPP_SGX_CONFIG)
  253. unsigned long
  254. stoul(const string& str, size_t* idx, int base)
  255. {
  256. return as_integer<unsigned long>( "stoul", str, idx, base );
  257. }
  258. // Implement support for wcstoxxx api in wchar.h
  259. #if !defined(_LIBCPP_SGX_CONFIG)
  260. unsigned long
  261. stoul(const wstring& str, size_t* idx, int base)
  262. {
  263. return as_integer<unsigned long>( "stoul", str, idx, base );
  264. }
  265. #endif // !defined(_LIBCPP_SGX_CONFIG)
  266. long long
  267. stoll(const string& str, size_t* idx, int base)
  268. {
  269. return as_integer<long long>( "stoll", str, idx, base );
  270. }
  271. // Implement support for wcstoxxx api in wchar.h
  272. #if !defined(_LIBCPP_SGX_CONFIG)
  273. long long
  274. stoll(const wstring& str, size_t* idx, int base)
  275. {
  276. return as_integer<long long>( "stoll", str, idx, base );
  277. }
  278. #endif // !defined(_LIBCPP_SGX_CONFIG)
  279. unsigned long long
  280. stoull(const string& str, size_t* idx, int base)
  281. {
  282. return as_integer<unsigned long long>( "stoull", str, idx, base );
  283. }
  284. // Implement support for wcstoxxx api in wchar.h
  285. #if !defined(_LIBCPP_SGX_CONFIG)
  286. unsigned long long
  287. stoull(const wstring& str, size_t* idx, int base)
  288. {
  289. return as_integer<unsigned long long>( "stoull", str, idx, base );
  290. }
  291. #endif // !defined(_LIBCPP_SGX_CONFIG)
  292. float
  293. stof(const string& str, size_t* idx)
  294. {
  295. return as_float<float>( "stof", str, idx );
  296. }
  297. // Implement support for wcstoxxx api in wchar.h
  298. #if !defined(_LIBCPP_SGX_CONFIG)
  299. float
  300. stof(const wstring& str, size_t* idx)
  301. {
  302. return as_float<float>( "stof", str, idx );
  303. }
  304. #endif // !defined(_LIBCPP_SGX_CONFIG)
  305. double
  306. stod(const string& str, size_t* idx)
  307. {
  308. return as_float<double>( "stod", str, idx );
  309. }
  310. // Implement support for wcstoxxx api in wchar.h
  311. #if !defined(_LIBCPP_SGX_CONFIG)
  312. double
  313. stod(const wstring& str, size_t* idx)
  314. {
  315. return as_float<double>( "stod", str, idx );
  316. }
  317. #endif // !defined(_LIBCPP_SGX_CONFIG)
  318. long double
  319. stold(const string& str, size_t* idx)
  320. {
  321. return as_float<long double>( "stold", str, idx );
  322. }
  323. // Implement support for wcstoxxx api in wchar.h
  324. #if !defined(_LIBCPP_SGX_CONFIG)
  325. long double
  326. stold(const wstring& str, size_t* idx)
  327. {
  328. return as_float<long double>( "stold", str, idx );
  329. }
  330. #endif // !defined(_LIBCPP_SGX_CONFIG)
  331. // to_string
  332. namespace
  333. {
  334. // as_string
  335. template<typename S, typename P, typename V >
  336. inline
  337. S
  338. as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
  339. {
  340. typedef typename S::size_type size_type;
  341. size_type available = s.size();
  342. while (true)
  343. {
  344. int status = sprintf_like(&s[0], available + 1, fmt, a);
  345. if ( status >= 0 )
  346. {
  347. size_type used = static_cast<size_type>(status);
  348. if ( used <= available )
  349. {
  350. s.resize( used );
  351. break;
  352. }
  353. available = used; // Assume this is advice of how much space we need.
  354. }
  355. else
  356. available = available * 2 + 1;
  357. s.resize(available);
  358. }
  359. return s;
  360. }
  361. template <class S, class V, bool = is_floating_point<V>::value>
  362. struct initial_string;
  363. template <class V, bool b>
  364. struct initial_string<string, V, b>
  365. {
  366. string
  367. operator()() const
  368. {
  369. string s;
  370. s.resize(s.capacity());
  371. return s;
  372. }
  373. };
  374. template <class V>
  375. struct initial_string<wstring, V, false>
  376. {
  377. wstring
  378. operator()() const
  379. {
  380. const size_t n = (numeric_limits<unsigned long long>::digits / 3)
  381. + ((numeric_limits<unsigned long long>::digits % 3) != 0)
  382. + 1;
  383. wstring s(n, wchar_t());
  384. s.resize(s.capacity());
  385. return s;
  386. }
  387. };
  388. template <class V>
  389. struct initial_string<wstring, V, true>
  390. {
  391. wstring
  392. operator()() const
  393. {
  394. wstring s(20, wchar_t());
  395. s.resize(s.capacity());
  396. return s;
  397. }
  398. };
  399. typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
  400. inline
  401. wide_printf
  402. get_swprintf()
  403. {
  404. #ifndef _LIBCPP_MSVCRT
  405. return swprintf;
  406. #else
  407. return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);
  408. #endif
  409. }
  410. } // unnamed namespace
  411. string to_string(int val)
  412. {
  413. return as_string(snprintf, initial_string<string, int>()(), "%d", val);
  414. }
  415. string to_string(unsigned val)
  416. {
  417. return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
  418. }
  419. string to_string(long val)
  420. {
  421. return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
  422. }
  423. string to_string(unsigned long val)
  424. {
  425. return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
  426. }
  427. string to_string(long long val)
  428. {
  429. return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
  430. }
  431. string to_string(unsigned long long val)
  432. {
  433. return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
  434. }
  435. string to_string(float val)
  436. {
  437. return as_string(snprintf, initial_string<string, float>()(), "%f", val);
  438. }
  439. string to_string(double val)
  440. {
  441. return as_string(snprintf, initial_string<string, double>()(), "%f", val);
  442. }
  443. string to_string(long double val)
  444. {
  445. return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
  446. }
  447. wstring to_wstring(int val)
  448. {
  449. return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
  450. }
  451. wstring to_wstring(unsigned val)
  452. {
  453. return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
  454. }
  455. wstring to_wstring(long val)
  456. {
  457. return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
  458. }
  459. wstring to_wstring(unsigned long val)
  460. {
  461. return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
  462. }
  463. wstring to_wstring(long long val)
  464. {
  465. return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
  466. }
  467. wstring to_wstring(unsigned long long val)
  468. {
  469. return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
  470. }
  471. wstring to_wstring(float val)
  472. {
  473. return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
  474. }
  475. wstring to_wstring(double val)
  476. {
  477. return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
  478. }
  479. wstring to_wstring(long double val)
  480. {
  481. return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
  482. }
  483. _LIBCPP_END_NAMESPACE_STD