blob: 7e651a1a8e0ac9f3406a202509d61d38a340f485 [file] [log] [blame]
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +00001//===------------------------- string.cpp ---------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Howard Hinnantee11c312010-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 Hinnanta5f4f8e2010-06-02 18:20:39 +00007//
8//===----------------------------------------------------------------------===//
9
10#include "string"
11#include "cstdlib"
12#include "cwchar"
13#include "cerrno"
14
15_LIBCPP_BEGIN_NAMESPACE_STD
16
17template class __basic_string_common<true>;
18
19template class basic_string<char>;
20template class basic_string<wchar_t>;
21
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000022template
23 string
24 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
25
26int
27stoi(const string& str, size_t* idx, int base)
28{
29 char* ptr;
30 const char* const p = str.c_str();
31 long r = strtol(p, &ptr, base);
32 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
33 ptr = const_cast<char*>(p);
34 if (ptr == p)
35 {
Howard Hinnant72f73582010-08-11 17:04:31 +000036#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000037 if (r == 0)
38 throw invalid_argument("stoi: no conversion");
39 throw out_of_range("stoi: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +000040#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000041 }
42 if (idx)
43 *idx = static_cast<size_t>(ptr - p);
44 return static_cast<int>(r);
45}
46
47int
48stoi(const wstring& str, size_t* idx, int base)
49{
50 wchar_t* ptr;
51 const wchar_t* const p = str.c_str();
52 long r = wcstol(p, &ptr, base);
53 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
54 ptr = const_cast<wchar_t*>(p);
55 if (ptr == p)
56 {
Howard Hinnant72f73582010-08-11 17:04:31 +000057#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000058 if (r == 0)
59 throw invalid_argument("stoi: no conversion");
60 throw out_of_range("stoi: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +000061#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000062 }
63 if (idx)
64 *idx = static_cast<size_t>(ptr - p);
65 return static_cast<int>(r);
66}
67
68long
69stol(const string& str, size_t* idx, int base)
70{
71 char* ptr;
72 const char* const p = str.c_str();
73 long r = strtol(p, &ptr, base);
74 if (ptr == p)
75 {
Howard Hinnant72f73582010-08-11 17:04:31 +000076#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000077 if (r == 0)
78 throw invalid_argument("stol: no conversion");
79 throw out_of_range("stol: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +000080#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000081 }
82 if (idx)
83 *idx = static_cast<size_t>(ptr - p);
84 return r;
85}
86
87long
88stol(const wstring& str, size_t* idx, int base)
89{
90 wchar_t* ptr;
91 const wchar_t* const p = str.c_str();
92 long r = wcstol(p, &ptr, base);
93 if (ptr == p)
94 {
Howard Hinnant72f73582010-08-11 17:04:31 +000095#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +000096 if (r == 0)
97 throw invalid_argument("stol: no conversion");
98 throw out_of_range("stol: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +000099#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000100 }
101 if (idx)
102 *idx = static_cast<size_t>(ptr - p);
103 return r;
104}
105
106unsigned long
107stoul(const string& str, size_t* idx, int base)
108{
109 char* ptr;
110 const char* const p = str.c_str();
111 unsigned long r = strtoul(p, &ptr, base);
112 if (ptr == p)
113 {
Howard Hinnant72f73582010-08-11 17:04:31 +0000114#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000115 if (r == 0)
116 throw invalid_argument("stoul: no conversion");
117 throw out_of_range("stoul: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000118#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000119 }
120 if (idx)
121 *idx = static_cast<size_t>(ptr - p);
122 return r;
123}
124
125unsigned long
126stoul(const wstring& str, size_t* idx, int base)
127{
128 wchar_t* ptr;
129 const wchar_t* const p = str.c_str();
130 unsigned long r = wcstoul(p, &ptr, base);
131 if (ptr == p)
132 {
Howard Hinnant72f73582010-08-11 17:04:31 +0000133#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000134 if (r == 0)
135 throw invalid_argument("stoul: no conversion");
136 throw out_of_range("stoul: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000137#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000138 }
139 if (idx)
140 *idx = static_cast<size_t>(ptr - p);
141 return r;
142}
143
144long long
145stoll(const string& str, size_t* idx, int base)
146{
147 char* ptr;
148 const char* const p = str.c_str();
149 long long r = strtoll(p, &ptr, base);
150 if (ptr == p)
151 {
Howard Hinnant72f73582010-08-11 17:04:31 +0000152#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000153 if (r == 0)
154 throw invalid_argument("stoll: no conversion");
155 throw out_of_range("stoll: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000156#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000157 }
158 if (idx)
159 *idx = static_cast<size_t>(ptr - p);
160 return r;
161}
162
163long long
164stoll(const wstring& str, size_t* idx, int base)
165{
166 wchar_t* ptr;
167 const wchar_t* const p = str.c_str();
168 long long r = wcstoll(p, &ptr, base);
169 if (ptr == p)
170 {
Howard Hinnant72f73582010-08-11 17:04:31 +0000171#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000172 if (r == 0)
173 throw invalid_argument("stoll: no conversion");
174 throw out_of_range("stoll: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000175#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000176 }
177 if (idx)
178 *idx = static_cast<size_t>(ptr - p);
179 return r;
180}
181
182unsigned long long
183stoull(const string& str, size_t* idx, int base)
184{
185 char* ptr;
186 const char* const p = str.c_str();
187 unsigned long long r = strtoull(p, &ptr, base);
188 if (ptr == p)
189 {
Howard Hinnant72f73582010-08-11 17:04:31 +0000190#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000191 if (r == 0)
192 throw invalid_argument("stoull: no conversion");
193 throw out_of_range("stoull: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000194#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000195 }
196 if (idx)
197 *idx = static_cast<size_t>(ptr - p);
198 return r;
199}
200
201unsigned long long
202stoull(const wstring& str, size_t* idx, int base)
203{
204 wchar_t* ptr;
205 const wchar_t* const p = str.c_str();
206 unsigned long long r = wcstoull(p, &ptr, base);
207 if (ptr == p)
208 {
Howard Hinnant72f73582010-08-11 17:04:31 +0000209#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000210 if (r == 0)
211 throw invalid_argument("stoull: no conversion");
212 throw out_of_range("stoull: out of range");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000213#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000214 }
215 if (idx)
216 *idx = static_cast<size_t>(ptr - p);
217 return r;
218}
219
220float
221stof(const string& str, size_t* idx)
222{
223 char* ptr;
224 const char* const p = str.c_str();
225 int errno_save = errno;
226 errno = 0;
227 double r = strtod(p, &ptr);
228 swap(errno, errno_save);
Howard Hinnant72f73582010-08-11 17:04:31 +0000229#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000230 if (errno_save == ERANGE)
231 throw out_of_range("stof: out of range");
232 if (ptr == p)
233 throw invalid_argument("stof: no conversion");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000234#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000235 if (idx)
236 *idx = static_cast<size_t>(ptr - p);
237 return static_cast<float>(r);
238}
239
240float
241stof(const wstring& str, size_t* idx)
242{
243 wchar_t* ptr;
244 const wchar_t* const p = str.c_str();
245 int errno_save = errno;
246 errno = 0;
247 double r = wcstod(p, &ptr);
248 swap(errno, errno_save);
Howard Hinnant72f73582010-08-11 17:04:31 +0000249#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000250 if (errno_save == ERANGE)
251 throw out_of_range("stof: out of range");
252 if (ptr == p)
253 throw invalid_argument("stof: no conversion");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000254#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000255 if (idx)
256 *idx = static_cast<size_t>(ptr - p);
257 return static_cast<float>(r);
258}
259
260double
261stod(const string& str, size_t* idx)
262{
263 char* ptr;
264 const char* const p = str.c_str();
265 int errno_save = errno;
266 errno = 0;
267 double r = strtod(p, &ptr);
268 swap(errno, errno_save);
Howard Hinnant72f73582010-08-11 17:04:31 +0000269#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000270 if (errno_save == ERANGE)
271 throw out_of_range("stod: out of range");
272 if (ptr == p)
273 throw invalid_argument("stod: no conversion");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000274#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000275 if (idx)
276 *idx = static_cast<size_t>(ptr - p);
277 return r;
278}
279
280double
281stod(const wstring& str, size_t* idx)
282{
283 wchar_t* ptr;
284 const wchar_t* const p = str.c_str();
285 int errno_save = errno;
286 errno = 0;
287 double r = wcstod(p, &ptr);
288 swap(errno, errno_save);
Howard Hinnant72f73582010-08-11 17:04:31 +0000289#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000290 if (errno_save == ERANGE)
291 throw out_of_range("stod: out of range");
292 if (ptr == p)
293 throw invalid_argument("stod: no conversion");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000294#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000295 if (idx)
296 *idx = static_cast<size_t>(ptr - p);
297 return r;
298}
299
300long double
301stold(const string& str, size_t* idx)
302{
303 char* ptr;
304 const char* const p = str.c_str();
305 int errno_save = errno;
306 errno = 0;
307 long double r = strtold(p, &ptr);
308 swap(errno, errno_save);
Howard Hinnant72f73582010-08-11 17:04:31 +0000309#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000310 if (errno_save == ERANGE)
311 throw out_of_range("stold: out of range");
312 if (ptr == p)
313 throw invalid_argument("stold: no conversion");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000314#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000315 if (idx)
316 *idx = static_cast<size_t>(ptr - p);
317 return r;
318}
319
320long double
321stold(const wstring& str, size_t* idx)
322{
323 wchar_t* ptr;
324 const wchar_t* const p = str.c_str();
325 int errno_save = errno;
326 errno = 0;
327 long double r = wcstold(p, &ptr);
328 swap(errno, errno_save);
Howard Hinnant72f73582010-08-11 17:04:31 +0000329#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000330 if (errno_save == ERANGE)
331 throw out_of_range("stold: out of range");
332 if (ptr == p)
333 throw invalid_argument("stold: no conversion");
Howard Hinnantffb308e2010-08-22 00:03:27 +0000334#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnanta5f4f8e2010-06-02 18:20:39 +0000335 if (idx)
336 *idx = static_cast<size_t>(ptr - p);
337 return r;
338}
339
340string to_string(int val)
341{
342 string s;
343 s.resize(s.capacity());
344 while (true)
345 {
346 int n2 = snprintf(&s[0], s.size()+1, "%d", val);
347 if (n2 <= s.size())
348 {
349 s.resize(n2);
350 break;
351 }
352 s.resize(n2);
353 }
354 return s;
355}
356
357string to_string(unsigned val)
358{
359 string s;
360 s.resize(s.capacity());
361 while (true)
362 {
363 int n2 = snprintf(&s[0], s.size()+1, "%u", val);
364 if (n2 <= s.size())
365 {
366 s.resize(n2);
367 break;
368 }
369 s.resize(n2);
370 }
371 return s;
372}
373
374string to_string(long val)
375{
376 string s;
377 s.resize(s.capacity());
378 while (true)
379 {
380 int n2 = snprintf(&s[0], s.size()+1, "%ld", val);
381 if (n2 <= s.size())
382 {
383 s.resize(n2);
384 break;
385 }
386 s.resize(n2);
387 }
388 return s;
389}
390
391string to_string(unsigned long val)
392{
393 string s;
394 s.resize(s.capacity());
395 while (true)
396 {
397 int n2 = snprintf(&s[0], s.size()+1, "%lu", val);
398 if (n2 <= s.size())
399 {
400 s.resize(n2);
401 break;
402 }
403 s.resize(n2);
404 }
405 return s;
406}
407
408string to_string(long long val)
409{
410 string s;
411 s.resize(s.capacity());
412 while (true)
413 {
414 int n2 = snprintf(&s[0], s.size()+1, "%lld", val);
415 if (n2 <= s.size())
416 {
417 s.resize(n2);
418 break;
419 }
420 s.resize(n2);
421 }
422 return s;
423}
424
425string to_string(unsigned long long val)
426{
427 string s;
428 s.resize(s.capacity());
429 while (true)
430 {
431 int n2 = snprintf(&s[0], s.size()+1, "%llu", val);
432 if (n2 <= s.size())
433 {
434 s.resize(n2);
435 break;
436 }
437 s.resize(n2);
438 }
439 return s;
440}
441
442string to_string(float val)
443{
444 string s;
445 s.resize(s.capacity());
446 while (true)
447 {
448 int n2 = snprintf(&s[0], s.size()+1, "%f", val);
449 if (n2 <= s.size())
450 {
451 s.resize(n2);
452 break;
453 }
454 s.resize(n2);
455 }
456 return s;
457}
458
459string to_string(double val)
460{
461 string s;
462 s.resize(s.capacity());
463 while (true)
464 {
465 int n2 = snprintf(&s[0], s.size()+1, "%f", val);
466 if (n2 <= s.size())
467 {
468 s.resize(n2);
469 break;
470 }
471 s.resize(n2);
472 }
473 return s;
474}
475
476string to_string(long double val)
477{
478 string s;
479 s.resize(s.capacity());
480 while (true)
481 {
482 int n2 = snprintf(&s[0], s.size()+1, "%Lf", val);
483 if (n2 <= s.size())
484 {
485 s.resize(n2);
486 break;
487 }
488 s.resize(n2);
489 }
490 return s;
491}
492
493wstring to_wstring(int val)
494{
495 const size_t n = (numeric_limits<int>::digits / 3)
496 + ((numeric_limits<int>::digits % 3) != 0)
497 + 1;
498 wstring s(n, wchar_t());
499 s.resize(s.capacity());
500 while (true)
501 {
502 int n2 = swprintf(&s[0], s.size()+1, L"%d", val);
503 if (n2 > 0)
504 {
505 s.resize(n2);
506 break;
507 }
508 s.resize(2*s.size());
509 s.resize(s.capacity());
510 }
511 return s;
512}
513
514wstring to_wstring(unsigned val)
515{
516 const size_t n = (numeric_limits<unsigned>::digits / 3)
517 + ((numeric_limits<unsigned>::digits % 3) != 0)
518 + 1;
519 wstring s(n, wchar_t());
520 s.resize(s.capacity());
521 while (true)
522 {
523 int n2 = swprintf(&s[0], s.size()+1, L"%u", val);
524 if (n2 > 0)
525 {
526 s.resize(n2);
527 break;
528 }
529 s.resize(2*s.size());
530 s.resize(s.capacity());
531 }
532 return s;
533}
534
535wstring to_wstring(long val)
536{
537 const size_t n = (numeric_limits<long>::digits / 3)
538 + ((numeric_limits<long>::digits % 3) != 0)
539 + 1;
540 wstring s(n, wchar_t());
541 s.resize(s.capacity());
542 while (true)
543 {
544 int n2 = swprintf(&s[0], s.size()+1, L"%ld", val);
545 if (n2 > 0)
546 {
547 s.resize(n2);
548 break;
549 }
550 s.resize(2*s.size());
551 s.resize(s.capacity());
552 }
553 return s;
554}
555
556wstring to_wstring(unsigned long val)
557{
558 const size_t n = (numeric_limits<unsigned long>::digits / 3)
559 + ((numeric_limits<unsigned long>::digits % 3) != 0)
560 + 1;
561 wstring s(n, wchar_t());
562 s.resize(s.capacity());
563 while (true)
564 {
565 int n2 = swprintf(&s[0], s.size()+1, L"%lu", val);
566 if (n2 > 0)
567 {
568 s.resize(n2);
569 break;
570 }
571 s.resize(2*s.size());
572 s.resize(s.capacity());
573 }
574 return s;
575}
576
577wstring to_wstring(long long val)
578{
579 const size_t n = (numeric_limits<long long>::digits / 3)
580 + ((numeric_limits<long long>::digits % 3) != 0)
581 + 1;
582 wstring s(n, wchar_t());
583 s.resize(s.capacity());
584 while (true)
585 {
586 int n2 = swprintf(&s[0], s.size()+1, L"%lld", val);
587 if (n2 > 0)
588 {
589 s.resize(n2);
590 break;
591 }
592 s.resize(2*s.size());
593 s.resize(s.capacity());
594 }
595 return s;
596}
597
598wstring to_wstring(unsigned long long val)
599{
600 const size_t n = (numeric_limits<unsigned long long>::digits / 3)
601 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
602 + 1;
603 wstring s(n, wchar_t());
604 s.resize(s.capacity());
605 while (true)
606 {
607 int n2 = swprintf(&s[0], s.size()+1, L"%llu", val);
608 if (n2 > 0)
609 {
610 s.resize(n2);
611 break;
612 }
613 s.resize(2*s.size());
614 s.resize(s.capacity());
615 }
616 return s;
617}
618
619wstring to_wstring(float val)
620{
621 const size_t n = 20;
622 wstring s(n, wchar_t());
623 s.resize(s.capacity());
624 while (true)
625 {
626 int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
627 if (n2 > 0)
628 {
629 s.resize(n2);
630 break;
631 }
632 s.resize(2*s.size());
633 s.resize(s.capacity());
634 }
635 return s;
636}
637
638wstring to_wstring(double val)
639{
640 const size_t n = 20;
641 wstring s(n, wchar_t());
642 s.resize(s.capacity());
643 while (true)
644 {
645 int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
646 if (n2 > 0)
647 {
648 s.resize(n2);
649 break;
650 }
651 s.resize(2*s.size());
652 s.resize(s.capacity());
653 }
654 return s;
655}
656
657wstring to_wstring(long double val)
658{
659 const size_t n = 20;
660 wstring s(n, wchar_t());
661 s.resize(s.capacity());
662 while (true)
663 {
664 int n2 = swprintf(&s[0], s.size()+1, L"%Lf", val);
665 if (n2 > 0)
666 {
667 s.resize(n2);
668 break;
669 }
670 s.resize(2*s.size());
671 s.resize(s.capacity());
672 }
673 return s;
674}
675
676_LIBCPP_END_NAMESPACE_STD