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