string.cpp revision 249989
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
20template class __basic_string_common<true>;
21
22template class basic_string<char>;
23template class basic_string<wchar_t>;
24
25template
26    string
27    operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
28
29int
30stoi(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
50int
51stoi(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
71long
72stol(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
91long
92stol(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
111unsigned long
112stoul(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
131unsigned long
132stoul(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
151long long
152stoll(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
171long long
172stoll(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
191unsigned long long
192stoull(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
211unsigned long long
212stoull(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
231float
232stof(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
251float
252stof(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
271double
272stod(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
291double
292stod(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
311long double
312stold(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
331long double
332stold(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
351string 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
368string 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
385string 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
402string 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
419string 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
436string 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
453string 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
470string 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
487string 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
504wstring 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
525wstring 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
546wstring 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
567wstring 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
588wstring 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
609wstring 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
630wstring 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
649wstring 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
668wstring 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
688