string.cpp revision 232924
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
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    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
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    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
71long
72stol(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
90long
91stol(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
109unsigned long
110stoul(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
128unsigned long
129stoul(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
147long long
148stoll(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
166long long
167stoll(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
185unsigned long long
186stoull(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
204unsigned long long
205stoull(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
223float
224stof(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
243float
244stof(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
263double
264stod(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
283double
284stod(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
303long double
304stold(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
323long double
324stold(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
343string 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
360string 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
377string 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
394string 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
411string 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
428string 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
445string 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
462string 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
479string 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
496wstring 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
517wstring 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
538wstring 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
559wstring 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
580wstring 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
601wstring 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
622wstring 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
641wstring 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
660wstring 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
680