blob: 1f58e3657a89a13e3fc8893bb8a1901dcb2df37e [file] [log] [blame]
Howard Hinnanta6a062d2010-06-02 18:20:39 +00001//===------------------------- string.cpp ---------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Howard Hinnantb64f8b02010-11-16 22:09:02 +00005// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnanta6a062d2010-06-02 18:20:39 +00007//
8//===----------------------------------------------------------------------===//
9
10#include "string"
11#include "cstdlib"
12#include "cwchar"
13#include "cerrno"
Howard Hinnant6cd05ee2011-09-23 16:11:27 +000014#if _WIN32
15#include "support/win32/support.h"
16#endif // _WIN32
Howard Hinnanta6a062d2010-06-02 18:20:39 +000017
18_LIBCPP_BEGIN_NAMESPACE_STD
19
20template class __basic_string_common<true>;
21
22template class basic_string<char>;
23template class basic_string<wchar_t>;
24
Howard Hinnanta6a062d2010-06-02 18:20:39 +000025template
26 string
27 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
28
29int
30stoi(const string& str, size_t* idx, int base)
31{
32 char* ptr;
33 const char* const p = str.c_str();
34 long r = strtol(p, &ptr, base);
35 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
36 ptr = const_cast<char*>(p);
37 if (ptr == p)
38 {
Howard Hinnantd4444702010-08-11 17:04:31 +000039#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +000040 if (r == 0)
41 throw invalid_argument("stoi: no conversion");
42 throw out_of_range("stoi: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +000043#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +000044 }
45 if (idx)
46 *idx = static_cast<size_t>(ptr - p);
47 return static_cast<int>(r);
48}
49
50int
51stoi(const wstring& str, size_t* idx, int base)
52{
53 wchar_t* ptr;
54 const wchar_t* const p = str.c_str();
55 long r = wcstol(p, &ptr, base);
56 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
57 ptr = const_cast<wchar_t*>(p);
58 if (ptr == p)
59 {
Howard Hinnantd4444702010-08-11 17:04:31 +000060#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +000061 if (r == 0)
62 throw invalid_argument("stoi: no conversion");
63 throw out_of_range("stoi: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +000064#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +000065 }
66 if (idx)
67 *idx = static_cast<size_t>(ptr - p);
68 return static_cast<int>(r);
69}
70
71long
72stol(const string& str, size_t* idx, int base)
73{
74 char* ptr;
75 const char* const p = str.c_str();
76 long r = strtol(p, &ptr, base);
77 if (ptr == p)
78 {
Howard Hinnantd4444702010-08-11 17:04:31 +000079#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +000080 if (r == 0)
81 throw invalid_argument("stol: no conversion");
82 throw out_of_range("stol: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +000083#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +000084 }
85 if (idx)
86 *idx = static_cast<size_t>(ptr - p);
87 return r;
88}
89
90long
91stol(const wstring& str, size_t* idx, int base)
92{
93 wchar_t* ptr;
94 const wchar_t* const p = str.c_str();
95 long r = wcstol(p, &ptr, base);
96 if (ptr == p)
97 {
Howard Hinnantd4444702010-08-11 17:04:31 +000098#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +000099 if (r == 0)
100 throw invalid_argument("stol: no conversion");
101 throw out_of_range("stol: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000102#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000103 }
104 if (idx)
105 *idx = static_cast<size_t>(ptr - p);
106 return r;
107}
108
109unsigned long
110stoul(const string& str, size_t* idx, int base)
111{
112 char* ptr;
113 const char* const p = str.c_str();
114 unsigned long r = strtoul(p, &ptr, base);
115 if (ptr == p)
116 {
Howard Hinnantd4444702010-08-11 17:04:31 +0000117#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000118 if (r == 0)
119 throw invalid_argument("stoul: no conversion");
120 throw out_of_range("stoul: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000121#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000122 }
123 if (idx)
124 *idx = static_cast<size_t>(ptr - p);
125 return r;
126}
127
128unsigned long
129stoul(const wstring& str, size_t* idx, int base)
130{
131 wchar_t* ptr;
132 const wchar_t* const p = str.c_str();
133 unsigned long r = wcstoul(p, &ptr, base);
134 if (ptr == p)
135 {
Howard Hinnantd4444702010-08-11 17:04:31 +0000136#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000137 if (r == 0)
138 throw invalid_argument("stoul: no conversion");
139 throw out_of_range("stoul: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000140#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000141 }
142 if (idx)
143 *idx = static_cast<size_t>(ptr - p);
144 return r;
145}
146
147long long
148stoll(const string& str, size_t* idx, int base)
149{
150 char* ptr;
151 const char* const p = str.c_str();
152 long long r = strtoll(p, &ptr, base);
153 if (ptr == p)
154 {
Howard Hinnantd4444702010-08-11 17:04:31 +0000155#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000156 if (r == 0)
157 throw invalid_argument("stoll: no conversion");
158 throw out_of_range("stoll: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000159#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000160 }
161 if (idx)
162 *idx = static_cast<size_t>(ptr - p);
163 return r;
164}
165
166long long
167stoll(const wstring& str, size_t* idx, int base)
168{
169 wchar_t* ptr;
170 const wchar_t* const p = str.c_str();
171 long long r = wcstoll(p, &ptr, base);
172 if (ptr == p)
173 {
Howard Hinnantd4444702010-08-11 17:04:31 +0000174#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000175 if (r == 0)
176 throw invalid_argument("stoll: no conversion");
177 throw out_of_range("stoll: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000178#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000179 }
180 if (idx)
181 *idx = static_cast<size_t>(ptr - p);
182 return r;
183}
184
185unsigned long long
186stoull(const string& str, size_t* idx, int base)
187{
188 char* ptr;
189 const char* const p = str.c_str();
190 unsigned long long r = strtoull(p, &ptr, base);
191 if (ptr == p)
192 {
Howard Hinnantd4444702010-08-11 17:04:31 +0000193#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000194 if (r == 0)
195 throw invalid_argument("stoull: no conversion");
196 throw out_of_range("stoull: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000197#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000198 }
199 if (idx)
200 *idx = static_cast<size_t>(ptr - p);
201 return r;
202}
203
204unsigned long long
205stoull(const wstring& str, size_t* idx, int base)
206{
207 wchar_t* ptr;
208 const wchar_t* const p = str.c_str();
209 unsigned long long r = wcstoull(p, &ptr, base);
210 if (ptr == p)
211 {
Howard Hinnantd4444702010-08-11 17:04:31 +0000212#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000213 if (r == 0)
214 throw invalid_argument("stoull: no conversion");
215 throw out_of_range("stoull: out of range");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000216#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000217 }
218 if (idx)
219 *idx = static_cast<size_t>(ptr - p);
220 return r;
221}
222
223float
224stof(const string& str, size_t* idx)
225{
226 char* ptr;
227 const char* const p = str.c_str();
228 int errno_save = errno;
229 errno = 0;
230 double r = strtod(p, &ptr);
231 swap(errno, errno_save);
Howard Hinnantd4444702010-08-11 17:04:31 +0000232#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000233 if (errno_save == ERANGE)
234 throw out_of_range("stof: out of range");
235 if (ptr == p)
236 throw invalid_argument("stof: no conversion");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000237#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000238 if (idx)
239 *idx = static_cast<size_t>(ptr - p);
240 return static_cast<float>(r);
241}
242
243float
244stof(const wstring& str, size_t* idx)
245{
246 wchar_t* ptr;
247 const wchar_t* const p = str.c_str();
248 int errno_save = errno;
249 errno = 0;
250 double r = wcstod(p, &ptr);
251 swap(errno, errno_save);
Howard Hinnantd4444702010-08-11 17:04:31 +0000252#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000253 if (errno_save == ERANGE)
254 throw out_of_range("stof: out of range");
255 if (ptr == p)
256 throw invalid_argument("stof: no conversion");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000257#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000258 if (idx)
259 *idx = static_cast<size_t>(ptr - p);
260 return static_cast<float>(r);
261}
262
263double
264stod(const string& str, size_t* idx)
265{
266 char* ptr;
267 const char* const p = str.c_str();
268 int errno_save = errno;
269 errno = 0;
270 double r = strtod(p, &ptr);
271 swap(errno, errno_save);
Howard Hinnantd4444702010-08-11 17:04:31 +0000272#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000273 if (errno_save == ERANGE)
274 throw out_of_range("stod: out of range");
275 if (ptr == p)
276 throw invalid_argument("stod: no conversion");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000277#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000278 if (idx)
279 *idx = static_cast<size_t>(ptr - p);
280 return r;
281}
282
283double
284stod(const wstring& str, size_t* idx)
285{
286 wchar_t* ptr;
287 const wchar_t* const p = str.c_str();
288 int errno_save = errno;
289 errno = 0;
290 double r = wcstod(p, &ptr);
291 swap(errno, errno_save);
Howard Hinnantd4444702010-08-11 17:04:31 +0000292#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000293 if (errno_save == ERANGE)
294 throw out_of_range("stod: out of range");
295 if (ptr == p)
296 throw invalid_argument("stod: no conversion");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000297#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000298 if (idx)
299 *idx = static_cast<size_t>(ptr - p);
300 return r;
301}
302
303long double
304stold(const string& str, size_t* idx)
305{
306 char* ptr;
307 const char* const p = str.c_str();
308 int errno_save = errno;
309 errno = 0;
310 long double r = strtold(p, &ptr);
311 swap(errno, errno_save);
Howard Hinnantd4444702010-08-11 17:04:31 +0000312#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000313 if (errno_save == ERANGE)
314 throw out_of_range("stold: out of range");
315 if (ptr == p)
316 throw invalid_argument("stold: no conversion");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000317#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000318 if (idx)
319 *idx = static_cast<size_t>(ptr - p);
320 return r;
321}
322
323long double
324stold(const wstring& str, size_t* idx)
325{
326 wchar_t* ptr;
327 const wchar_t* const p = str.c_str();
328 int errno_save = errno;
329 errno = 0;
330 long double r = wcstold(p, &ptr);
331 swap(errno, errno_save);
Howard Hinnantd4444702010-08-11 17:04:31 +0000332#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000333 if (errno_save == ERANGE)
334 throw out_of_range("stold: out of range");
335 if (ptr == p)
336 throw invalid_argument("stold: no conversion");
Howard Hinnant16e6e1d2010-08-22 00:03:27 +0000337#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta6a062d2010-06-02 18:20:39 +0000338 if (idx)
339 *idx = static_cast<size_t>(ptr - p);
340 return r;
341}
342
343string to_string(int val)
344{
345 string s;
346 s.resize(s.capacity());
347 while (true)
348 {
349 int n2 = snprintf(&s[0], s.size()+1, "%d", val);
350 if (n2 <= s.size())
351 {
352 s.resize(n2);
353 break;
354 }
355 s.resize(n2);
356 }
357 return s;
358}
359
360string to_string(unsigned val)
361{
362 string s;
363 s.resize(s.capacity());
364 while (true)
365 {
366 int n2 = snprintf(&s[0], s.size()+1, "%u", val);
367 if (n2 <= s.size())
368 {
369 s.resize(n2);
370 break;
371 }
372 s.resize(n2);
373 }
374 return s;
375}
376
377string to_string(long val)
378{
379 string s;
380 s.resize(s.capacity());
381 while (true)
382 {
383 int n2 = snprintf(&s[0], s.size()+1, "%ld", val);
384 if (n2 <= s.size())
385 {
386 s.resize(n2);
387 break;
388 }
389 s.resize(n2);
390 }
391 return s;
392}
393
394string to_string(unsigned long val)
395{
396 string s;
397 s.resize(s.capacity());
398 while (true)
399 {
400 int n2 = snprintf(&s[0], s.size()+1, "%lu", val);
401 if (n2 <= s.size())
402 {
403 s.resize(n2);
404 break;
405 }
406 s.resize(n2);
407 }
408 return s;
409}
410
411string to_string(long long val)
412{
413 string s;
414 s.resize(s.capacity());
415 while (true)
416 {
417 int n2 = snprintf(&s[0], s.size()+1, "%lld", val);
418 if (n2 <= s.size())
419 {
420 s.resize(n2);
421 break;
422 }
423 s.resize(n2);
424 }
425 return s;
426}
427
428string to_string(unsigned long long val)
429{
430 string s;
431 s.resize(s.capacity());
432 while (true)
433 {
434 int n2 = snprintf(&s[0], s.size()+1, "%llu", val);
435 if (n2 <= s.size())
436 {
437 s.resize(n2);
438 break;
439 }
440 s.resize(n2);
441 }
442 return s;
443}
444
445string to_string(float val)
446{
447 string s;
448 s.resize(s.capacity());
449 while (true)
450 {
451 int n2 = snprintf(&s[0], s.size()+1, "%f", val);
452 if (n2 <= s.size())
453 {
454 s.resize(n2);
455 break;
456 }
457 s.resize(n2);
458 }
459 return s;
460}
461
462string to_string(double val)
463{
464 string s;
465 s.resize(s.capacity());
466 while (true)
467 {
468 int n2 = snprintf(&s[0], s.size()+1, "%f", val);
469 if (n2 <= s.size())
470 {
471 s.resize(n2);
472 break;
473 }
474 s.resize(n2);
475 }
476 return s;
477}
478
479string to_string(long double val)
480{
481 string s;
482 s.resize(s.capacity());
483 while (true)
484 {
485 int n2 = snprintf(&s[0], s.size()+1, "%Lf", val);
486 if (n2 <= s.size())
487 {
488 s.resize(n2);
489 break;
490 }
491 s.resize(n2);
492 }
493 return s;
494}
495
496wstring to_wstring(int val)
497{
498 const size_t n = (numeric_limits<int>::digits / 3)
499 + ((numeric_limits<int>::digits % 3) != 0)
500 + 1;
501 wstring s(n, wchar_t());
502 s.resize(s.capacity());
503 while (true)
504 {
505 int n2 = swprintf(&s[0], s.size()+1, L"%d", val);
506 if (n2 > 0)
507 {
508 s.resize(n2);
509 break;
510 }
511 s.resize(2*s.size());
512 s.resize(s.capacity());
513 }
514 return s;
515}
516
517wstring to_wstring(unsigned val)
518{
519 const size_t n = (numeric_limits<unsigned>::digits / 3)
520 + ((numeric_limits<unsigned>::digits % 3) != 0)
521 + 1;
522 wstring s(n, wchar_t());
523 s.resize(s.capacity());
524 while (true)
525 {
526 int n2 = swprintf(&s[0], s.size()+1, L"%u", val);
527 if (n2 > 0)
528 {
529 s.resize(n2);
530 break;
531 }
532 s.resize(2*s.size());
533 s.resize(s.capacity());
534 }
535 return s;
536}
537
538wstring to_wstring(long val)
539{
540 const size_t n = (numeric_limits<long>::digits / 3)
541 + ((numeric_limits<long>::digits % 3) != 0)
542 + 1;
543 wstring s(n, wchar_t());
544 s.resize(s.capacity());
545 while (true)
546 {
547 int n2 = swprintf(&s[0], s.size()+1, L"%ld", val);
548 if (n2 > 0)
549 {
550 s.resize(n2);
551 break;
552 }
553 s.resize(2*s.size());
554 s.resize(s.capacity());
555 }
556 return s;
557}
558
559wstring to_wstring(unsigned long val)
560{
561 const size_t n = (numeric_limits<unsigned long>::digits / 3)
562 + ((numeric_limits<unsigned long>::digits % 3) != 0)
563 + 1;
564 wstring s(n, wchar_t());
565 s.resize(s.capacity());
566 while (true)
567 {
568 int n2 = swprintf(&s[0], s.size()+1, L"%lu", val);
569 if (n2 > 0)
570 {
571 s.resize(n2);
572 break;
573 }
574 s.resize(2*s.size());
575 s.resize(s.capacity());
576 }
577 return s;
578}
579
580wstring to_wstring(long long val)
581{
582 const size_t n = (numeric_limits<long long>::digits / 3)
583 + ((numeric_limits<long long>::digits % 3) != 0)
584 + 1;
585 wstring s(n, wchar_t());
586 s.resize(s.capacity());
587 while (true)
588 {
589 int n2 = swprintf(&s[0], s.size()+1, L"%lld", val);
590 if (n2 > 0)
591 {
592 s.resize(n2);
593 break;
594 }
595 s.resize(2*s.size());
596 s.resize(s.capacity());
597 }
598 return s;
599}
600
601wstring to_wstring(unsigned long long val)
602{
603 const size_t n = (numeric_limits<unsigned long long>::digits / 3)
604 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
605 + 1;
606 wstring s(n, wchar_t());
607 s.resize(s.capacity());
608 while (true)
609 {
610 int n2 = swprintf(&s[0], s.size()+1, L"%llu", val);
611 if (n2 > 0)
612 {
613 s.resize(n2);
614 break;
615 }
616 s.resize(2*s.size());
617 s.resize(s.capacity());
618 }
619 return s;
620}
621
622wstring to_wstring(float val)
623{
624 const size_t n = 20;
625 wstring s(n, wchar_t());
626 s.resize(s.capacity());
627 while (true)
628 {
629 int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
630 if (n2 > 0)
631 {
632 s.resize(n2);
633 break;
634 }
635 s.resize(2*s.size());
636 s.resize(s.capacity());
637 }
638 return s;
639}
640
641wstring to_wstring(double val)
642{
643 const size_t n = 20;
644 wstring s(n, wchar_t());
645 s.resize(s.capacity());
646 while (true)
647 {
648 int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
649 if (n2 > 0)
650 {
651 s.resize(n2);
652 break;
653 }
654 s.resize(2*s.size());
655 s.resize(s.capacity());
656 }
657 return s;
658}
659
660wstring to_wstring(long double val)
661{
662 const size_t n = 20;
663 wstring s(n, wchar_t());
664 s.resize(s.capacity());
665 while (true)
666 {
667 int n2 = swprintf(&s[0], s.size()+1, L"%Lf", val);
668 if (n2 > 0)
669 {
670 s.resize(n2);
671 break;
672 }
673 s.resize(2*s.size());
674 s.resize(s.capacity());
675 }
676 return s;
677}
678
679_LIBCPP_END_NAMESPACE_STD