blob: 5eaed282e49ecf5ca366e34b16abb5f21aefec8a [file] [log] [blame]
Howard Hinnantcbbf6332010-06-02 18:20:391//===------------------------- string.cpp ---------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Howard Hinnant412dbeb2010-11-16 22:09:025// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
Howard Hinnantcbbf6332010-06-02 18:20:397//
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
22template enable_if<__is_forward_iterator<char const*>::value, void>::type
23 basic_string<char, char_traits<char>, allocator<char> >
24 ::__init<char const*>(char const*, char const*);
25
26template enable_if<__is_forward_iterator<wchar_t const*>::value, void>::type
27 basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >
28 ::__init<wchar_t const*>(wchar_t const*, wchar_t const*);
29
30template
31 enable_if<__is_forward_iterator<char*>::value,
32 basic_string<char, char_traits<char>, allocator<char> >&>::type
33 basic_string<char, char_traits<char>, allocator<char> >::
34 append<char*>(char*, char*);
35
36template
37 enable_if<__is_forward_iterator<wchar_t*>::value,
38 basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >&>::type
39 basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >::
40 append<wchar_t*>(wchar_t*, wchar_t*);
41
42template
43 enable_if<__is_forward_iterator<char const*>::value,
44 string::iterator>::type
45 string::
46 insert<char const*>(string::const_iterator, char const*, char const*);
47
48template
49 enable_if<__is_forward_iterator<wchar_t const*>::value,
50 wstring::iterator>::type
51 wstring::
52 insert<wchar_t const*>(wstring::const_iterator, wchar_t const*, wchar_t const*);
53
54template
55 enable_if<__is_input_iterator<char const*>::value, string&>::type
56 string::
57 replace<char const*>(string::iterator, string::iterator, char const*, char const*);
58
59template
60 enable_if<__is_input_iterator<wchar_t const*>::value, wstring&>::type
61 wstring::
62 replace<wchar_t const*>(wstring::iterator, wstring::iterator, wchar_t const*, wchar_t const*);
63
64template
65 enable_if<__is_forward_iterator<wchar_t*>::value, wstring&>::type
66 wstring::assign<wchar_t*>(wchar_t*, wchar_t*);
67
68template
69 string
70 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
71
72int
73stoi(const string& str, size_t* idx, int base)
74{
75 char* ptr;
76 const char* const p = str.c_str();
77 long r = strtol(p, &ptr, base);
78 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
79 ptr = const_cast<char*>(p);
80 if (ptr == p)
81 {
Howard Hinnant54b409f2010-08-11 17:04:3182#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:3983 if (r == 0)
84 throw invalid_argument("stoi: no conversion");
85 throw out_of_range("stoi: out of range");
Howard Hinnant940e2112010-08-22 00:03:2786#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:3987 }
88 if (idx)
89 *idx = static_cast<size_t>(ptr - p);
90 return static_cast<int>(r);
91}
92
93int
94stoi(const wstring& str, size_t* idx, int base)
95{
96 wchar_t* ptr;
97 const wchar_t* const p = str.c_str();
98 long r = wcstol(p, &ptr, base);
99 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
100 ptr = const_cast<wchar_t*>(p);
101 if (ptr == p)
102 {
Howard Hinnant54b409f2010-08-11 17:04:31103#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39104 if (r == 0)
105 throw invalid_argument("stoi: no conversion");
106 throw out_of_range("stoi: out of range");
Howard Hinnant940e2112010-08-22 00:03:27107#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39108 }
109 if (idx)
110 *idx = static_cast<size_t>(ptr - p);
111 return static_cast<int>(r);
112}
113
114long
115stol(const string& str, size_t* idx, int base)
116{
117 char* ptr;
118 const char* const p = str.c_str();
119 long r = strtol(p, &ptr, base);
120 if (ptr == p)
121 {
Howard Hinnant54b409f2010-08-11 17:04:31122#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39123 if (r == 0)
124 throw invalid_argument("stol: no conversion");
125 throw out_of_range("stol: out of range");
Howard Hinnant940e2112010-08-22 00:03:27126#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39127 }
128 if (idx)
129 *idx = static_cast<size_t>(ptr - p);
130 return r;
131}
132
133long
134stol(const wstring& str, size_t* idx, int base)
135{
136 wchar_t* ptr;
137 const wchar_t* const p = str.c_str();
138 long r = wcstol(p, &ptr, base);
139 if (ptr == p)
140 {
Howard Hinnant54b409f2010-08-11 17:04:31141#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39142 if (r == 0)
143 throw invalid_argument("stol: no conversion");
144 throw out_of_range("stol: out of range");
Howard Hinnant940e2112010-08-22 00:03:27145#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39146 }
147 if (idx)
148 *idx = static_cast<size_t>(ptr - p);
149 return r;
150}
151
152unsigned long
153stoul(const string& str, size_t* idx, int base)
154{
155 char* ptr;
156 const char* const p = str.c_str();
157 unsigned long r = strtoul(p, &ptr, base);
158 if (ptr == p)
159 {
Howard Hinnant54b409f2010-08-11 17:04:31160#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39161 if (r == 0)
162 throw invalid_argument("stoul: no conversion");
163 throw out_of_range("stoul: out of range");
Howard Hinnant940e2112010-08-22 00:03:27164#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39165 }
166 if (idx)
167 *idx = static_cast<size_t>(ptr - p);
168 return r;
169}
170
171unsigned long
172stoul(const wstring& str, size_t* idx, int base)
173{
174 wchar_t* ptr;
175 const wchar_t* const p = str.c_str();
176 unsigned long r = wcstoul(p, &ptr, base);
177 if (ptr == p)
178 {
Howard Hinnant54b409f2010-08-11 17:04:31179#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39180 if (r == 0)
181 throw invalid_argument("stoul: no conversion");
182 throw out_of_range("stoul: out of range");
Howard Hinnant940e2112010-08-22 00:03:27183#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39184 }
185 if (idx)
186 *idx = static_cast<size_t>(ptr - p);
187 return r;
188}
189
190long long
191stoll(const string& str, size_t* idx, int base)
192{
193 char* ptr;
194 const char* const p = str.c_str();
195 long long r = strtoll(p, &ptr, base);
196 if (ptr == p)
197 {
Howard Hinnant54b409f2010-08-11 17:04:31198#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39199 if (r == 0)
200 throw invalid_argument("stoll: no conversion");
201 throw out_of_range("stoll: out of range");
Howard Hinnant940e2112010-08-22 00:03:27202#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39203 }
204 if (idx)
205 *idx = static_cast<size_t>(ptr - p);
206 return r;
207}
208
209long long
210stoll(const wstring& str, size_t* idx, int base)
211{
212 wchar_t* ptr;
213 const wchar_t* const p = str.c_str();
214 long long r = wcstoll(p, &ptr, base);
215 if (ptr == p)
216 {
Howard Hinnant54b409f2010-08-11 17:04:31217#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39218 if (r == 0)
219 throw invalid_argument("stoll: no conversion");
220 throw out_of_range("stoll: out of range");
Howard Hinnant940e2112010-08-22 00:03:27221#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39222 }
223 if (idx)
224 *idx = static_cast<size_t>(ptr - p);
225 return r;
226}
227
228unsigned long long
229stoull(const string& str, size_t* idx, int base)
230{
231 char* ptr;
232 const char* const p = str.c_str();
233 unsigned long long r = strtoull(p, &ptr, base);
234 if (ptr == p)
235 {
Howard Hinnant54b409f2010-08-11 17:04:31236#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39237 if (r == 0)
238 throw invalid_argument("stoull: no conversion");
239 throw out_of_range("stoull: out of range");
Howard Hinnant940e2112010-08-22 00:03:27240#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39241 }
242 if (idx)
243 *idx = static_cast<size_t>(ptr - p);
244 return r;
245}
246
247unsigned long long
248stoull(const wstring& str, size_t* idx, int base)
249{
250 wchar_t* ptr;
251 const wchar_t* const p = str.c_str();
252 unsigned long long r = wcstoull(p, &ptr, base);
253 if (ptr == p)
254 {
Howard Hinnant54b409f2010-08-11 17:04:31255#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39256 if (r == 0)
257 throw invalid_argument("stoull: no conversion");
258 throw out_of_range("stoull: out of range");
Howard Hinnant940e2112010-08-22 00:03:27259#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39260 }
261 if (idx)
262 *idx = static_cast<size_t>(ptr - p);
263 return r;
264}
265
266float
267stof(const string& str, size_t* idx)
268{
269 char* ptr;
270 const char* const p = str.c_str();
271 int errno_save = errno;
272 errno = 0;
273 double r = strtod(p, &ptr);
274 swap(errno, errno_save);
Howard Hinnant54b409f2010-08-11 17:04:31275#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39276 if (errno_save == ERANGE)
277 throw out_of_range("stof: out of range");
278 if (ptr == p)
279 throw invalid_argument("stof: no conversion");
Howard Hinnant940e2112010-08-22 00:03:27280#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39281 if (idx)
282 *idx = static_cast<size_t>(ptr - p);
283 return static_cast<float>(r);
284}
285
286float
287stof(const wstring& str, size_t* idx)
288{
289 wchar_t* ptr;
290 const wchar_t* const p = str.c_str();
291 int errno_save = errno;
292 errno = 0;
293 double r = wcstod(p, &ptr);
294 swap(errno, errno_save);
Howard Hinnant54b409f2010-08-11 17:04:31295#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39296 if (errno_save == ERANGE)
297 throw out_of_range("stof: out of range");
298 if (ptr == p)
299 throw invalid_argument("stof: no conversion");
Howard Hinnant940e2112010-08-22 00:03:27300#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39301 if (idx)
302 *idx = static_cast<size_t>(ptr - p);
303 return static_cast<float>(r);
304}
305
306double
307stod(const string& str, size_t* idx)
308{
309 char* ptr;
310 const char* const p = str.c_str();
311 int errno_save = errno;
312 errno = 0;
313 double r = strtod(p, &ptr);
314 swap(errno, errno_save);
Howard Hinnant54b409f2010-08-11 17:04:31315#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39316 if (errno_save == ERANGE)
317 throw out_of_range("stod: out of range");
318 if (ptr == p)
319 throw invalid_argument("stod: no conversion");
Howard Hinnant940e2112010-08-22 00:03:27320#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39321 if (idx)
322 *idx = static_cast<size_t>(ptr - p);
323 return r;
324}
325
326double
327stod(const wstring& str, size_t* idx)
328{
329 wchar_t* ptr;
330 const wchar_t* const p = str.c_str();
331 int errno_save = errno;
332 errno = 0;
333 double r = wcstod(p, &ptr);
334 swap(errno, errno_save);
Howard Hinnant54b409f2010-08-11 17:04:31335#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39336 if (errno_save == ERANGE)
337 throw out_of_range("stod: out of range");
338 if (ptr == p)
339 throw invalid_argument("stod: no conversion");
Howard Hinnant940e2112010-08-22 00:03:27340#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39341 if (idx)
342 *idx = static_cast<size_t>(ptr - p);
343 return r;
344}
345
346long double
347stold(const string& str, size_t* idx)
348{
349 char* ptr;
350 const char* const p = str.c_str();
351 int errno_save = errno;
352 errno = 0;
353 long double r = strtold(p, &ptr);
354 swap(errno, errno_save);
Howard Hinnant54b409f2010-08-11 17:04:31355#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39356 if (errno_save == ERANGE)
357 throw out_of_range("stold: out of range");
358 if (ptr == p)
359 throw invalid_argument("stold: no conversion");
Howard Hinnant940e2112010-08-22 00:03:27360#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39361 if (idx)
362 *idx = static_cast<size_t>(ptr - p);
363 return r;
364}
365
366long double
367stold(const wstring& str, size_t* idx)
368{
369 wchar_t* ptr;
370 const wchar_t* const p = str.c_str();
371 int errno_save = errno;
372 errno = 0;
373 long double r = wcstold(p, &ptr);
374 swap(errno, errno_save);
Howard Hinnant54b409f2010-08-11 17:04:31375#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39376 if (errno_save == ERANGE)
377 throw out_of_range("stold: out of range");
378 if (ptr == p)
379 throw invalid_argument("stold: no conversion");
Howard Hinnant940e2112010-08-22 00:03:27380#endif // _LIBCPP_NO_EXCEPTIONS
Howard Hinnantcbbf6332010-06-02 18:20:39381 if (idx)
382 *idx = static_cast<size_t>(ptr - p);
383 return r;
384}
385
386string to_string(int val)
387{
388 string s;
389 s.resize(s.capacity());
390 while (true)
391 {
392 int n2 = snprintf(&s[0], s.size()+1, "%d", val);
393 if (n2 <= s.size())
394 {
395 s.resize(n2);
396 break;
397 }
398 s.resize(n2);
399 }
400 return s;
401}
402
403string to_string(unsigned val)
404{
405 string s;
406 s.resize(s.capacity());
407 while (true)
408 {
409 int n2 = snprintf(&s[0], s.size()+1, "%u", val);
410 if (n2 <= s.size())
411 {
412 s.resize(n2);
413 break;
414 }
415 s.resize(n2);
416 }
417 return s;
418}
419
420string to_string(long val)
421{
422 string s;
423 s.resize(s.capacity());
424 while (true)
425 {
426 int n2 = snprintf(&s[0], s.size()+1, "%ld", val);
427 if (n2 <= s.size())
428 {
429 s.resize(n2);
430 break;
431 }
432 s.resize(n2);
433 }
434 return s;
435}
436
437string to_string(unsigned long val)
438{
439 string s;
440 s.resize(s.capacity());
441 while (true)
442 {
443 int n2 = snprintf(&s[0], s.size()+1, "%lu", val);
444 if (n2 <= s.size())
445 {
446 s.resize(n2);
447 break;
448 }
449 s.resize(n2);
450 }
451 return s;
452}
453
454string to_string(long long val)
455{
456 string s;
457 s.resize(s.capacity());
458 while (true)
459 {
460 int n2 = snprintf(&s[0], s.size()+1, "%lld", val);
461 if (n2 <= s.size())
462 {
463 s.resize(n2);
464 break;
465 }
466 s.resize(n2);
467 }
468 return s;
469}
470
471string to_string(unsigned long long val)
472{
473 string s;
474 s.resize(s.capacity());
475 while (true)
476 {
477 int n2 = snprintf(&s[0], s.size()+1, "%llu", val);
478 if (n2 <= s.size())
479 {
480 s.resize(n2);
481 break;
482 }
483 s.resize(n2);
484 }
485 return s;
486}
487
488string to_string(float val)
489{
490 string s;
491 s.resize(s.capacity());
492 while (true)
493 {
494 int n2 = snprintf(&s[0], s.size()+1, "%f", val);
495 if (n2 <= s.size())
496 {
497 s.resize(n2);
498 break;
499 }
500 s.resize(n2);
501 }
502 return s;
503}
504
505string to_string(double val)
506{
507 string s;
508 s.resize(s.capacity());
509 while (true)
510 {
511 int n2 = snprintf(&s[0], s.size()+1, "%f", val);
512 if (n2 <= s.size())
513 {
514 s.resize(n2);
515 break;
516 }
517 s.resize(n2);
518 }
519 return s;
520}
521
522string to_string(long double val)
523{
524 string s;
525 s.resize(s.capacity());
526 while (true)
527 {
528 int n2 = snprintf(&s[0], s.size()+1, "%Lf", val);
529 if (n2 <= s.size())
530 {
531 s.resize(n2);
532 break;
533 }
534 s.resize(n2);
535 }
536 return s;
537}
538
539wstring to_wstring(int val)
540{
541 const size_t n = (numeric_limits<int>::digits / 3)
542 + ((numeric_limits<int>::digits % 3) != 0)
543 + 1;
544 wstring s(n, wchar_t());
545 s.resize(s.capacity());
546 while (true)
547 {
548 int n2 = swprintf(&s[0], s.size()+1, L"%d", val);
549 if (n2 > 0)
550 {
551 s.resize(n2);
552 break;
553 }
554 s.resize(2*s.size());
555 s.resize(s.capacity());
556 }
557 return s;
558}
559
560wstring to_wstring(unsigned val)
561{
562 const size_t n = (numeric_limits<unsigned>::digits / 3)
563 + ((numeric_limits<unsigned>::digits % 3) != 0)
564 + 1;
565 wstring s(n, wchar_t());
566 s.resize(s.capacity());
567 while (true)
568 {
569 int n2 = swprintf(&s[0], s.size()+1, L"%u", val);
570 if (n2 > 0)
571 {
572 s.resize(n2);
573 break;
574 }
575 s.resize(2*s.size());
576 s.resize(s.capacity());
577 }
578 return s;
579}
580
581wstring to_wstring(long val)
582{
583 const size_t n = (numeric_limits<long>::digits / 3)
584 + ((numeric_limits<long>::digits % 3) != 0)
585 + 1;
586 wstring s(n, wchar_t());
587 s.resize(s.capacity());
588 while (true)
589 {
590 int n2 = swprintf(&s[0], s.size()+1, L"%ld", val);
591 if (n2 > 0)
592 {
593 s.resize(n2);
594 break;
595 }
596 s.resize(2*s.size());
597 s.resize(s.capacity());
598 }
599 return s;
600}
601
602wstring to_wstring(unsigned long val)
603{
604 const size_t n = (numeric_limits<unsigned long>::digits / 3)
605 + ((numeric_limits<unsigned long>::digits % 3) != 0)
606 + 1;
607 wstring s(n, wchar_t());
608 s.resize(s.capacity());
609 while (true)
610 {
611 int n2 = swprintf(&s[0], s.size()+1, L"%lu", val);
612 if (n2 > 0)
613 {
614 s.resize(n2);
615 break;
616 }
617 s.resize(2*s.size());
618 s.resize(s.capacity());
619 }
620 return s;
621}
622
623wstring to_wstring(long long val)
624{
625 const size_t n = (numeric_limits<long long>::digits / 3)
626 + ((numeric_limits<long long>::digits % 3) != 0)
627 + 1;
628 wstring s(n, wchar_t());
629 s.resize(s.capacity());
630 while (true)
631 {
632 int n2 = swprintf(&s[0], s.size()+1, L"%lld", val);
633 if (n2 > 0)
634 {
635 s.resize(n2);
636 break;
637 }
638 s.resize(2*s.size());
639 s.resize(s.capacity());
640 }
641 return s;
642}
643
644wstring to_wstring(unsigned long long val)
645{
646 const size_t n = (numeric_limits<unsigned long long>::digits / 3)
647 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
648 + 1;
649 wstring s(n, wchar_t());
650 s.resize(s.capacity());
651 while (true)
652 {
653 int n2 = swprintf(&s[0], s.size()+1, L"%llu", val);
654 if (n2 > 0)
655 {
656 s.resize(n2);
657 break;
658 }
659 s.resize(2*s.size());
660 s.resize(s.capacity());
661 }
662 return s;
663}
664
665wstring to_wstring(float val)
666{
667 const size_t n = 20;
668 wstring s(n, wchar_t());
669 s.resize(s.capacity());
670 while (true)
671 {
672 int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
673 if (n2 > 0)
674 {
675 s.resize(n2);
676 break;
677 }
678 s.resize(2*s.size());
679 s.resize(s.capacity());
680 }
681 return s;
682}
683
684wstring to_wstring(double val)
685{
686 const size_t n = 20;
687 wstring s(n, wchar_t());
688 s.resize(s.capacity());
689 while (true)
690 {
691 int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
692 if (n2 > 0)
693 {
694 s.resize(n2);
695 break;
696 }
697 s.resize(2*s.size());
698 s.resize(s.capacity());
699 }
700 return s;
701}
702
703wstring to_wstring(long double val)
704{
705 const size_t n = 20;
706 wstring s(n, wchar_t());
707 s.resize(s.capacity());
708 while (true)
709 {
710 int n2 = swprintf(&s[0], s.size()+1, L"%Lf", val);
711 if (n2 > 0)
712 {
713 s.resize(n2);
714 break;
715 }
716 s.resize(2*s.size());
717 s.resize(s.capacity());
718 }
719 return s;
720}
721
722_LIBCPP_END_NAMESPACE_STD