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