]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/libc++/src/string.cpp
Merged libcxxrt and libc++. Now available for testing on 9-stable with
[FreeBSD/stable/9.git] / contrib / libc++ / src / string.cpp
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
10 #include "string"
11 #include "cstdlib"
12 #include "cwchar"
13 #include "cerrno"
14 #if _WIN32
15 #include "support/win32/support.h"
16 #endif // _WIN32
17
18 _LIBCPP_BEGIN_NAMESPACE_STD
19
20 template class __basic_string_common<true>;
21
22 template class basic_string<char>;
23 template class basic_string<wchar_t>;
24
25 template
26     string
27     operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
28
29 int
30 stoi(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     {
39 #ifndef _LIBCPP_NO_EXCEPTIONS
40         if (r == 0)
41             throw invalid_argument("stoi: no conversion");
42         throw out_of_range("stoi: out of range");
43 #endif  // _LIBCPP_NO_EXCEPTIONS
44     }
45     if (idx)
46         *idx = static_cast<size_t>(ptr - p);
47     return static_cast<int>(r);
48 }
49
50 int
51 stoi(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     {
60 #ifndef _LIBCPP_NO_EXCEPTIONS
61         if (r == 0)
62             throw invalid_argument("stoi: no conversion");
63         throw out_of_range("stoi: out of range");
64 #endif  // _LIBCPP_NO_EXCEPTIONS
65     }
66     if (idx)
67         *idx = static_cast<size_t>(ptr - p);
68     return static_cast<int>(r);
69 }
70
71 long
72 stol(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     {
79 #ifndef _LIBCPP_NO_EXCEPTIONS
80         if (r == 0)
81             throw invalid_argument("stol: no conversion");
82         throw out_of_range("stol: out of range");
83 #endif  // _LIBCPP_NO_EXCEPTIONS
84     }
85     if (idx)
86         *idx = static_cast<size_t>(ptr - p);
87     return r;
88 }
89
90 long
91 stol(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     {
98 #ifndef _LIBCPP_NO_EXCEPTIONS
99         if (r == 0)
100             throw invalid_argument("stol: no conversion");
101         throw out_of_range("stol: out of range");
102 #endif  // _LIBCPP_NO_EXCEPTIONS
103     }
104     if (idx)
105         *idx = static_cast<size_t>(ptr - p);
106     return r;
107 }
108
109 unsigned long
110 stoul(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     {
117 #ifndef _LIBCPP_NO_EXCEPTIONS
118         if (r == 0)
119             throw invalid_argument("stoul: no conversion");
120         throw out_of_range("stoul: out of range");
121 #endif  // _LIBCPP_NO_EXCEPTIONS
122     }
123     if (idx)
124         *idx = static_cast<size_t>(ptr - p);
125     return r;
126 }
127
128 unsigned long
129 stoul(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     {
136 #ifndef _LIBCPP_NO_EXCEPTIONS
137         if (r == 0)
138             throw invalid_argument("stoul: no conversion");
139         throw out_of_range("stoul: out of range");
140 #endif  // _LIBCPP_NO_EXCEPTIONS
141     }
142     if (idx)
143         *idx = static_cast<size_t>(ptr - p);
144     return r;
145 }
146
147 long long
148 stoll(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     {
155 #ifndef _LIBCPP_NO_EXCEPTIONS
156         if (r == 0)
157             throw invalid_argument("stoll: no conversion");
158         throw out_of_range("stoll: out of range");
159 #endif  // _LIBCPP_NO_EXCEPTIONS
160     }
161     if (idx)
162         *idx = static_cast<size_t>(ptr - p);
163     return r;
164 }
165
166 long long
167 stoll(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     {
174 #ifndef _LIBCPP_NO_EXCEPTIONS
175         if (r == 0)
176             throw invalid_argument("stoll: no conversion");
177         throw out_of_range("stoll: out of range");
178 #endif  // _LIBCPP_NO_EXCEPTIONS
179     }
180     if (idx)
181         *idx = static_cast<size_t>(ptr - p);
182     return r;
183 }
184
185 unsigned long long
186 stoull(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     {
193 #ifndef _LIBCPP_NO_EXCEPTIONS
194         if (r == 0)
195             throw invalid_argument("stoull: no conversion");
196         throw out_of_range("stoull: out of range");
197 #endif  // _LIBCPP_NO_EXCEPTIONS
198     }
199     if (idx)
200         *idx = static_cast<size_t>(ptr - p);
201     return r;
202 }
203
204 unsigned long long
205 stoull(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     {
212 #ifndef _LIBCPP_NO_EXCEPTIONS
213         if (r == 0)
214             throw invalid_argument("stoull: no conversion");
215         throw out_of_range("stoull: out of range");
216 #endif  // _LIBCPP_NO_EXCEPTIONS
217     }
218     if (idx)
219         *idx = static_cast<size_t>(ptr - p);
220     return r;
221 }
222
223 float
224 stof(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);
232 #ifndef _LIBCPP_NO_EXCEPTIONS
233     if (errno_save == ERANGE)
234         throw out_of_range("stof: out of range");
235     if (ptr == p)
236         throw invalid_argument("stof: no conversion");
237 #endif  // _LIBCPP_NO_EXCEPTIONS
238     if (idx)
239         *idx = static_cast<size_t>(ptr - p);
240     return static_cast<float>(r);
241 }
242
243 float
244 stof(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);
252 #ifndef _LIBCPP_NO_EXCEPTIONS
253     if (errno_save == ERANGE)
254         throw out_of_range("stof: out of range");
255     if (ptr == p)
256         throw invalid_argument("stof: no conversion");
257 #endif  // _LIBCPP_NO_EXCEPTIONS
258     if (idx)
259         *idx = static_cast<size_t>(ptr - p);
260     return static_cast<float>(r);
261 }
262
263 double
264 stod(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);
272 #ifndef _LIBCPP_NO_EXCEPTIONS
273     if (errno_save == ERANGE)
274         throw out_of_range("stod: out of range");
275     if (ptr == p)
276         throw invalid_argument("stod: no conversion");
277 #endif  // _LIBCPP_NO_EXCEPTIONS
278     if (idx)
279         *idx = static_cast<size_t>(ptr - p);
280     return r;
281 }
282
283 double
284 stod(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);
292 #ifndef _LIBCPP_NO_EXCEPTIONS
293     if (errno_save == ERANGE)
294         throw out_of_range("stod: out of range");
295     if (ptr == p)
296         throw invalid_argument("stod: no conversion");
297 #endif  // _LIBCPP_NO_EXCEPTIONS
298     if (idx)
299         *idx = static_cast<size_t>(ptr - p);
300     return r;
301 }
302
303 long double
304 stold(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);
312 #ifndef _LIBCPP_NO_EXCEPTIONS
313     if (errno_save == ERANGE)
314         throw out_of_range("stold: out of range");
315     if (ptr == p)
316         throw invalid_argument("stold: no conversion");
317 #endif  // _LIBCPP_NO_EXCEPTIONS
318     if (idx)
319         *idx = static_cast<size_t>(ptr - p);
320     return r;
321 }
322
323 long double
324 stold(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);
332 #ifndef _LIBCPP_NO_EXCEPTIONS
333     if (errno_save == ERANGE)
334         throw out_of_range("stold: out of range");
335     if (ptr == p)
336         throw invalid_argument("stold: no conversion");
337 #endif  // _LIBCPP_NO_EXCEPTIONS
338     if (idx)
339         *idx = static_cast<size_t>(ptr - p);
340     return r;
341 }
342
343 string to_string(int val)
344 {
345     string s;
346     s.resize(s.capacity());
347     while (true)
348     {
349         size_t n2 = static_cast<size_t>(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
360 string to_string(unsigned val)
361 {
362     string s;
363     s.resize(s.capacity());
364     while (true)
365     {
366         size_t n2 = static_cast<size_t>(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
377 string to_string(long val)
378 {
379     string s;
380     s.resize(s.capacity());
381     while (true)
382     {
383         size_t n2 = static_cast<size_t>(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
394 string to_string(unsigned long val)
395 {
396     string s;
397     s.resize(s.capacity());
398     while (true)
399     {
400         size_t n2 = static_cast<size_t>(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
411 string to_string(long long val)
412 {
413     string s;
414     s.resize(s.capacity());
415     while (true)
416     {
417         size_t n2 = static_cast<size_t>(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
428 string to_string(unsigned long long val)
429 {
430     string s;
431     s.resize(s.capacity());
432     while (true)
433     {
434         size_t n2 = static_cast<size_t>(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
445 string to_string(float val)
446 {
447     string s;
448     s.resize(s.capacity());
449     while (true)
450     {
451         size_t n2 = static_cast<size_t>(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
462 string to_string(double val)
463 {
464     string s;
465     s.resize(s.capacity());
466     while (true)
467     {
468         size_t n2 = static_cast<size_t>(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
479 string to_string(long double val)
480 {
481     string s;
482     s.resize(s.capacity());
483     while (true)
484     {
485         size_t n2 = static_cast<size_t>(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
496 wstring 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(static_cast<size_t>(n2));
509             break;
510         }
511         s.resize(2*s.size());
512         s.resize(s.capacity());
513     }
514     return s;
515 }
516
517 wstring 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(static_cast<size_t>(n2));
530             break;
531         }
532         s.resize(2*s.size());
533         s.resize(s.capacity());
534     }
535     return s;
536 }
537
538 wstring 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(static_cast<size_t>(n2));
551             break;
552         }
553         s.resize(2*s.size());
554         s.resize(s.capacity());
555     }
556     return s;
557 }
558
559 wstring 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(static_cast<size_t>(n2));
572             break;
573         }
574         s.resize(2*s.size());
575         s.resize(s.capacity());
576     }
577     return s;
578 }
579
580 wstring 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(static_cast<size_t>(n2));
593             break;
594         }
595         s.resize(2*s.size());
596         s.resize(s.capacity());
597     }
598     return s;
599 }
600
601 wstring 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(static_cast<size_t>(n2));
614             break;
615         }
616         s.resize(2*s.size());
617         s.resize(s.capacity());
618     }
619     return s;
620 }
621
622 wstring 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(static_cast<size_t>(n2));
633             break;
634         }
635         s.resize(2*s.size());
636         s.resize(s.capacity());
637     }
638     return s;
639 }
640
641 wstring 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(static_cast<size_t>(n2));
652             break;
653         }
654         s.resize(2*s.size());
655         s.resize(s.capacity());
656     }
657     return s;
658 }
659
660 wstring 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(static_cast<size_t>(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