blob: 819935c07d0edac788b9e07fca197fa85fa5ab8e [file] [log] [blame]
Howard Hinnantcbbf6332010-06-02 18:20:391//===------------------------- string.cpp ---------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
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 {
82 if (r == 0)
83 throw invalid_argument("stoi: no conversion");
84 throw out_of_range("stoi: out of range");
85 }
86 if (idx)
87 *idx = static_cast<size_t>(ptr - p);
88 return static_cast<int>(r);
89}
90
91int
92stoi(const wstring& str, size_t* idx, int base)
93{
94 wchar_t* ptr;
95 const wchar_t* const p = str.c_str();
96 long r = wcstol(p, &ptr, base);
97 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
98 ptr = const_cast<wchar_t*>(p);
99 if (ptr == p)
100 {
101 if (r == 0)
102 throw invalid_argument("stoi: no conversion");
103 throw out_of_range("stoi: out of range");
104 }
105 if (idx)
106 *idx = static_cast<size_t>(ptr - p);
107 return static_cast<int>(r);
108}
109
110long
111stol(const string& str, size_t* idx, int base)
112{
113 char* ptr;
114 const char* const p = str.c_str();
115 long r = strtol(p, &ptr, base);
116 if (ptr == p)
117 {
118 if (r == 0)
119 throw invalid_argument("stol: no conversion");
120 throw out_of_range("stol: out of range");
121 }
122 if (idx)
123 *idx = static_cast<size_t>(ptr - p);
124 return r;
125}
126
127long
128stol(const wstring& str, size_t* idx, int base)
129{
130 wchar_t* ptr;
131 const wchar_t* const p = str.c_str();
132 long r = wcstol(p, &ptr, base);
133 if (ptr == p)
134 {
135 if (r == 0)
136 throw invalid_argument("stol: no conversion");
137 throw out_of_range("stol: out of range");
138 }
139 if (idx)
140 *idx = static_cast<size_t>(ptr - p);
141 return r;
142}
143
144unsigned long
145stoul(const string& str, size_t* idx, int base)
146{
147 char* ptr;
148 const char* const p = str.c_str();
149 unsigned long r = strtoul(p, &ptr, base);
150 if (ptr == p)
151 {
152 if (r == 0)
153 throw invalid_argument("stoul: no conversion");
154 throw out_of_range("stoul: out of range");
155 }
156 if (idx)
157 *idx = static_cast<size_t>(ptr - p);
158 return r;
159}
160
161unsigned long
162stoul(const wstring& str, size_t* idx, int base)
163{
164 wchar_t* ptr;
165 const wchar_t* const p = str.c_str();
166 unsigned long r = wcstoul(p, &ptr, base);
167 if (ptr == p)
168 {
169 if (r == 0)
170 throw invalid_argument("stoul: no conversion");
171 throw out_of_range("stoul: out of range");
172 }
173 if (idx)
174 *idx = static_cast<size_t>(ptr - p);
175 return r;
176}
177
178long long
179stoll(const string& str, size_t* idx, int base)
180{
181 char* ptr;
182 const char* const p = str.c_str();
183 long long r = strtoll(p, &ptr, base);
184 if (ptr == p)
185 {
186 if (r == 0)
187 throw invalid_argument("stoll: no conversion");
188 throw out_of_range("stoll: out of range");
189 }
190 if (idx)
191 *idx = static_cast<size_t>(ptr - p);
192 return r;
193}
194
195long long
196stoll(const wstring& str, size_t* idx, int base)
197{
198 wchar_t* ptr;
199 const wchar_t* const p = str.c_str();
200 long long r = wcstoll(p, &ptr, base);
201 if (ptr == p)
202 {
203 if (r == 0)
204 throw invalid_argument("stoll: no conversion");
205 throw out_of_range("stoll: out of range");
206 }
207 if (idx)
208 *idx = static_cast<size_t>(ptr - p);
209 return r;
210}
211
212unsigned long long
213stoull(const string& str, size_t* idx, int base)
214{
215 char* ptr;
216 const char* const p = str.c_str();
217 unsigned long long r = strtoull(p, &ptr, base);
218 if (ptr == p)
219 {
220 if (r == 0)
221 throw invalid_argument("stoull: no conversion");
222 throw out_of_range("stoull: out of range");
223 }
224 if (idx)
225 *idx = static_cast<size_t>(ptr - p);
226 return r;
227}
228
229unsigned long long
230stoull(const wstring& str, size_t* idx, int base)
231{
232 wchar_t* ptr;
233 const wchar_t* const p = str.c_str();
234 unsigned long long r = wcstoull(p, &ptr, base);
235 if (ptr == p)
236 {
237 if (r == 0)
238 throw invalid_argument("stoull: no conversion");
239 throw out_of_range("stoull: out of range");
240 }
241 if (idx)
242 *idx = static_cast<size_t>(ptr - p);
243 return r;
244}
245
246float
247stof(const string& str, size_t* idx)
248{
249 char* ptr;
250 const char* const p = str.c_str();
251 int errno_save = errno;
252 errno = 0;
253 double r = strtod(p, &ptr);
254 swap(errno, errno_save);
255 if (errno_save == ERANGE)
256 throw out_of_range("stof: out of range");
257 if (ptr == p)
258 throw invalid_argument("stof: no conversion");
259 if (idx)
260 *idx = static_cast<size_t>(ptr - p);
261 return static_cast<float>(r);
262}
263
264float
265stof(const wstring& str, size_t* idx)
266{
267 wchar_t* ptr;
268 const wchar_t* const p = str.c_str();
269 int errno_save = errno;
270 errno = 0;
271 double r = wcstod(p, &ptr);
272 swap(errno, errno_save);
273 if (errno_save == ERANGE)
274 throw out_of_range("stof: out of range");
275 if (ptr == p)
276 throw invalid_argument("stof: no conversion");
277 if (idx)
278 *idx = static_cast<size_t>(ptr - p);
279 return static_cast<float>(r);
280}
281
282double
283stod(const string& str, size_t* idx)
284{
285 char* ptr;
286 const char* const p = str.c_str();
287 int errno_save = errno;
288 errno = 0;
289 double r = strtod(p, &ptr);
290 swap(errno, errno_save);
291 if (errno_save == ERANGE)
292 throw out_of_range("stod: out of range");
293 if (ptr == p)
294 throw invalid_argument("stod: no conversion");
295 if (idx)
296 *idx = static_cast<size_t>(ptr - p);
297 return r;
298}
299
300double
301stod(const wstring& str, size_t* idx)
302{
303 wchar_t* ptr;
304 const wchar_t* const p = str.c_str();
305 int errno_save = errno;
306 errno = 0;
307 double r = wcstod(p, &ptr);
308 swap(errno, errno_save);
309 if (errno_save == ERANGE)
310 throw out_of_range("stod: out of range");
311 if (ptr == p)
312 throw invalid_argument("stod: no conversion");
313 if (idx)
314 *idx = static_cast<size_t>(ptr - p);
315 return r;
316}
317
318long double
319stold(const string& str, size_t* idx)
320{
321 char* ptr;
322 const char* const p = str.c_str();
323 int errno_save = errno;
324 errno = 0;
325 long double r = strtold(p, &ptr);
326 swap(errno, errno_save);
327 if (errno_save == ERANGE)
328 throw out_of_range("stold: out of range");
329 if (ptr == p)
330 throw invalid_argument("stold: no conversion");
331 if (idx)
332 *idx = static_cast<size_t>(ptr - p);
333 return r;
334}
335
336long double
337stold(const wstring& str, size_t* idx)
338{
339 wchar_t* ptr;
340 const wchar_t* const p = str.c_str();
341 int errno_save = errno;
342 errno = 0;
343 long double r = wcstold(p, &ptr);
344 swap(errno, errno_save);
345 if (errno_save == ERANGE)
346 throw out_of_range("stold: out of range");
347 if (ptr == p)
348 throw invalid_argument("stold: no conversion");
349 if (idx)
350 *idx = static_cast<size_t>(ptr - p);
351 return r;
352}
353
354string to_string(int val)
355{
356 string s;
357 s.resize(s.capacity());
358 while (true)
359 {
360 int n2 = snprintf(&s[0], s.size()+1, "%d", val);
361 if (n2 <= s.size())
362 {
363 s.resize(n2);
364 break;
365 }
366 s.resize(n2);
367 }
368 return s;
369}
370
371string to_string(unsigned val)
372{
373 string s;
374 s.resize(s.capacity());
375 while (true)
376 {
377 int n2 = snprintf(&s[0], s.size()+1, "%u", val);
378 if (n2 <= s.size())
379 {
380 s.resize(n2);
381 break;
382 }
383 s.resize(n2);
384 }
385 return s;
386}
387
388string to_string(long val)
389{
390 string s;
391 s.resize(s.capacity());
392 while (true)
393 {
394 int n2 = snprintf(&s[0], s.size()+1, "%ld", val);
395 if (n2 <= s.size())
396 {
397 s.resize(n2);
398 break;
399 }
400 s.resize(n2);
401 }
402 return s;
403}
404
405string to_string(unsigned long val)
406{
407 string s;
408 s.resize(s.capacity());
409 while (true)
410 {
411 int n2 = snprintf(&s[0], s.size()+1, "%lu", val);
412 if (n2 <= s.size())
413 {
414 s.resize(n2);
415 break;
416 }
417 s.resize(n2);
418 }
419 return s;
420}
421
422string to_string(long long val)
423{
424 string s;
425 s.resize(s.capacity());
426 while (true)
427 {
428 int n2 = snprintf(&s[0], s.size()+1, "%lld", val);
429 if (n2 <= s.size())
430 {
431 s.resize(n2);
432 break;
433 }
434 s.resize(n2);
435 }
436 return s;
437}
438
439string to_string(unsigned long long val)
440{
441 string s;
442 s.resize(s.capacity());
443 while (true)
444 {
445 int n2 = snprintf(&s[0], s.size()+1, "%llu", val);
446 if (n2 <= s.size())
447 {
448 s.resize(n2);
449 break;
450 }
451 s.resize(n2);
452 }
453 return s;
454}
455
456string to_string(float val)
457{
458 string s;
459 s.resize(s.capacity());
460 while (true)
461 {
462 int n2 = snprintf(&s[0], s.size()+1, "%f", val);
463 if (n2 <= s.size())
464 {
465 s.resize(n2);
466 break;
467 }
468 s.resize(n2);
469 }
470 return s;
471}
472
473string to_string(double val)
474{
475 string s;
476 s.resize(s.capacity());
477 while (true)
478 {
479 int n2 = snprintf(&s[0], s.size()+1, "%f", val);
480 if (n2 <= s.size())
481 {
482 s.resize(n2);
483 break;
484 }
485 s.resize(n2);
486 }
487 return s;
488}
489
490string to_string(long double val)
491{
492 string s;
493 s.resize(s.capacity());
494 while (true)
495 {
496 int n2 = snprintf(&s[0], s.size()+1, "%Lf", val);
497 if (n2 <= s.size())
498 {
499 s.resize(n2);
500 break;
501 }
502 s.resize(n2);
503 }
504 return s;
505}
506
507wstring to_wstring(int val)
508{
509 const size_t n = (numeric_limits<int>::digits / 3)
510 + ((numeric_limits<int>::digits % 3) != 0)
511 + 1;
512 wstring s(n, wchar_t());
513 s.resize(s.capacity());
514 while (true)
515 {
516 int n2 = swprintf(&s[0], s.size()+1, L"%d", val);
517 if (n2 > 0)
518 {
519 s.resize(n2);
520 break;
521 }
522 s.resize(2*s.size());
523 s.resize(s.capacity());
524 }
525 return s;
526}
527
528wstring to_wstring(unsigned val)
529{
530 const size_t n = (numeric_limits<unsigned>::digits / 3)
531 + ((numeric_limits<unsigned>::digits % 3) != 0)
532 + 1;
533 wstring s(n, wchar_t());
534 s.resize(s.capacity());
535 while (true)
536 {
537 int n2 = swprintf(&s[0], s.size()+1, L"%u", val);
538 if (n2 > 0)
539 {
540 s.resize(n2);
541 break;
542 }
543 s.resize(2*s.size());
544 s.resize(s.capacity());
545 }
546 return s;
547}
548
549wstring to_wstring(long val)
550{
551 const size_t n = (numeric_limits<long>::digits / 3)
552 + ((numeric_limits<long>::digits % 3) != 0)
553 + 1;
554 wstring s(n, wchar_t());
555 s.resize(s.capacity());
556 while (true)
557 {
558 int n2 = swprintf(&s[0], s.size()+1, L"%ld", val);
559 if (n2 > 0)
560 {
561 s.resize(n2);
562 break;
563 }
564 s.resize(2*s.size());
565 s.resize(s.capacity());
566 }
567 return s;
568}
569
570wstring to_wstring(unsigned long val)
571{
572 const size_t n = (numeric_limits<unsigned long>::digits / 3)
573 + ((numeric_limits<unsigned long>::digits % 3) != 0)
574 + 1;
575 wstring s(n, wchar_t());
576 s.resize(s.capacity());
577 while (true)
578 {
579 int n2 = swprintf(&s[0], s.size()+1, L"%lu", val);
580 if (n2 > 0)
581 {
582 s.resize(n2);
583 break;
584 }
585 s.resize(2*s.size());
586 s.resize(s.capacity());
587 }
588 return s;
589}
590
591wstring to_wstring(long long val)
592{
593 const size_t n = (numeric_limits<long long>::digits / 3)
594 + ((numeric_limits<long long>::digits % 3) != 0)
595 + 1;
596 wstring s(n, wchar_t());
597 s.resize(s.capacity());
598 while (true)
599 {
600 int n2 = swprintf(&s[0], s.size()+1, L"%lld", val);
601 if (n2 > 0)
602 {
603 s.resize(n2);
604 break;
605 }
606 s.resize(2*s.size());
607 s.resize(s.capacity());
608 }
609 return s;
610}
611
612wstring to_wstring(unsigned long long val)
613{
614 const size_t n = (numeric_limits<unsigned long long>::digits / 3)
615 + ((numeric_limits<unsigned long long>::digits % 3) != 0)
616 + 1;
617 wstring s(n, wchar_t());
618 s.resize(s.capacity());
619 while (true)
620 {
621 int n2 = swprintf(&s[0], s.size()+1, L"%llu", val);
622 if (n2 > 0)
623 {
624 s.resize(n2);
625 break;
626 }
627 s.resize(2*s.size());
628 s.resize(s.capacity());
629 }
630 return s;
631}
632
633wstring to_wstring(float val)
634{
635 const size_t n = 20;
636 wstring s(n, wchar_t());
637 s.resize(s.capacity());
638 while (true)
639 {
640 int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
641 if (n2 > 0)
642 {
643 s.resize(n2);
644 break;
645 }
646 s.resize(2*s.size());
647 s.resize(s.capacity());
648 }
649 return s;
650}
651
652wstring to_wstring(double val)
653{
654 const size_t n = 20;
655 wstring s(n, wchar_t());
656 s.resize(s.capacity());
657 while (true)
658 {
659 int n2 = swprintf(&s[0], s.size()+1, L"%f", val);
660 if (n2 > 0)
661 {
662 s.resize(n2);
663 break;
664 }
665 s.resize(2*s.size());
666 s.resize(s.capacity());
667 }
668 return s;
669}
670
671wstring to_wstring(long double val)
672{
673 const size_t n = 20;
674 wstring s(n, wchar_t());
675 s.resize(s.capacity());
676 while (true)
677 {
678 int n2 = swprintf(&s[0], s.size()+1, L"%Lf", val);
679 if (n2 > 0)
680 {
681 s.resize(n2);
682 break;
683 }
684 s.resize(2*s.size());
685 s.resize(s.capacity());
686 }
687 return s;
688}
689
690_LIBCPP_END_NAMESPACE_STD