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 #define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
     11 
     12 #include "string"
     13 #include "cstdlib"
     14 #include "cwchar"
     15 #include "cerrno"
     16 #include "limits"
     17 #include "stdexcept"
     18 #ifdef _LIBCPP_MSVCRT
     19 #include "support/win32/support.h"
     20 #endif // _LIBCPP_MSVCRT
     21 #include <stdio.h>
     22 
     23 _LIBCPP_BEGIN_NAMESPACE_STD
     24 
     25 template class __basic_string_common<true>;
     26 
     27 template class basic_string<char>;
     28 template class basic_string<wchar_t>;
     29 
     30 template
     31     string
     32     operator+<char, char_traits<char>, allocator<char> >(char const*, string const&);
     33 
     34 namespace
     35 {
     36 
     37 template<typename T>
     38 inline
     39 void throw_helper( const string& msg )
     40 {
     41 #ifndef _LIBCPP_NO_EXCEPTIONS
     42     throw T( msg );
     43 #else
     44     printf("%s\n", msg.c_str());
     45     abort();
     46 #endif
     47 }
     48 
     49 inline
     50 void throw_from_string_out_of_range( const string& func )
     51 {
     52     throw_helper<out_of_range>(func + ": out of range");
     53 }
     54 
     55 inline
     56 void throw_from_string_invalid_arg( const string& func )
     57 {
     58     throw_helper<invalid_argument>(func + ": no conversion");
     59 }
     60 
     61 // as_integer
     62 
     63 template<typename V, typename S, typename F>
     64 inline
     65 V
     66 as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f)
     67 {
     68     typename S::value_type* ptr;
     69     const typename S::value_type* const p = str.c_str();
     70     typename remove_reference<decltype(errno)>::type errno_save = errno;
     71     errno = 0;
     72     V r = f(p, &ptr, base);
     73     swap(errno, errno_save);
     74     if (errno_save == ERANGE)
     75         throw_from_string_out_of_range(func);
     76     if (ptr == p)
     77         throw_from_string_invalid_arg(func);
     78     if (idx)
     79         *idx = static_cast<size_t>(ptr - p);
     80     return r;
     81 }
     82 
     83 template<typename V, typename S>
     84 inline
     85 V
     86 as_integer(const string& func, const S& s, size_t* idx, int base);
     87 
     88 // string
     89 template<>
     90 inline
     91 int
     92 as_integer(const string& func, const string& s, size_t* idx, int base )
     93 {
     94     // Use long as no Standard string to integer exists.
     95     long r = as_integer_helper<long>( func, s, idx, base, strtol );
     96     if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
     97         throw_from_string_out_of_range(func);
     98     return static_cast<int>(r);
     99 }
    100 
    101 template<>
    102 inline
    103 long
    104 as_integer(const string& func, const string& s, size_t* idx, int base )
    105 {
    106     return as_integer_helper<long>( func, s, idx, base, strtol );
    107 }
    108 
    109 template<>
    110 inline
    111 unsigned long
    112 as_integer( const string& func, const string& s, size_t* idx, int base )
    113 {
    114     return as_integer_helper<unsigned long>( func, s, idx, base, strtoul );
    115 }
    116 
    117 template<>
    118 inline
    119 long long
    120 as_integer( const string& func, const string& s, size_t* idx, int base )
    121 {
    122     return as_integer_helper<long long>( func, s, idx, base, strtoll );
    123 }
    124 
    125 template<>
    126 inline
    127 unsigned long long
    128 as_integer( const string& func, const string& s, size_t* idx, int base )
    129 {
    130     return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull );
    131 }
    132 
    133 // wstring
    134 template<>
    135 inline
    136 int
    137 as_integer( const string& func, const wstring& s, size_t* idx, int base )
    138 {
    139     // Use long as no Stantard string to integer exists.
    140     long r = as_integer_helper<long>( func, s, idx, base, wcstol );
    141     if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r)
    142         throw_from_string_out_of_range(func);
    143     return static_cast<int>(r);
    144 }
    145 
    146 template<>
    147 inline
    148 long
    149 as_integer( const string& func, const wstring& s, size_t* idx, int base )
    150 {
    151     return as_integer_helper<long>( func, s, idx, base, wcstol );
    152 }
    153 
    154 template<>
    155 inline
    156 unsigned long
    157 as_integer( const string& func, const wstring& s, size_t* idx, int base )
    158 {
    159     return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul );
    160 }
    161 
    162 template<>
    163 inline
    164 long long
    165 as_integer( const string& func, const wstring& s, size_t* idx, int base )
    166 {
    167     return as_integer_helper<long long>( func, s, idx, base, wcstoll );
    168 }
    169 
    170 template<>
    171 inline
    172 unsigned long long
    173 as_integer( const string& func, const wstring& s, size_t* idx, int base )
    174 {
    175     return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull );
    176 }
    177 
    178 // as_float
    179 
    180 template<typename V, typename S, typename F>
    181 inline
    182 V
    183 as_float_helper(const string& func, const S& str, size_t* idx, F f )
    184 {
    185     typename S::value_type* ptr;
    186     const typename S::value_type* const p = str.c_str();
    187     typename remove_reference<decltype(errno)>::type errno_save = errno;
    188     errno = 0;
    189     V r = static_cast<V>(f(p, &ptr));
    190     swap(errno, errno_save);
    191     if (errno_save == ERANGE)
    192         throw_from_string_out_of_range(func);
    193     if (ptr == p)
    194         throw_from_string_invalid_arg(func);
    195     if (idx)
    196         *idx = static_cast<size_t>(ptr - p);
    197     return r;
    198 }
    199 
    200 template<typename V, typename S>
    201 inline
    202 V as_float( const string& func, const S& s, size_t* idx = nullptr );
    203 
    204 template<>
    205 inline
    206 float
    207 as_float( const string& func, const string& s, size_t* idx )
    208 {
    209     return as_float_helper<float>( func, s, idx, strtod );
    210 }
    211 
    212 template<>
    213 inline
    214 double
    215 as_float(const string& func, const string& s, size_t* idx )
    216 {
    217     return as_float_helper<double>( func, s, idx, strtod );
    218 }
    219 
    220 template<>
    221 inline
    222 long double
    223 as_float( const string& func, const string& s, size_t* idx )
    224 {
    225     return as_float_helper<long double>( func, s, idx, strtold );
    226 }
    227 
    228 template<>
    229 inline
    230 float
    231 as_float( const string& func, const wstring& s, size_t* idx )
    232 {
    233     return as_float_helper<float>( func, s, idx, wcstod );
    234 }
    235 
    236 template<>
    237 inline
    238 double
    239 as_float( const string& func, const wstring& s, size_t* idx )
    240 {
    241     return as_float_helper<double>( func, s, idx, wcstod );
    242 }
    243 
    244 template<>
    245 inline
    246 long double
    247 as_float( const string& func, const wstring& s, size_t* idx )
    248 {
    249     return as_float_helper<long double>( func, s, idx, wcstold );
    250 }
    251 
    252 }  // unnamed namespace
    253 
    254 int
    255 stoi(const string& str, size_t* idx, int base)
    256 {
    257     return as_integer<int>( "stoi", str, idx, base );
    258 }
    259 
    260 int
    261 stoi(const wstring& str, size_t* idx, int base)
    262 {
    263     return as_integer<int>( "stoi", str, idx, base );
    264 }
    265 
    266 long
    267 stol(const string& str, size_t* idx, int base)
    268 {
    269     return as_integer<long>( "stol", str, idx, base );
    270 }
    271 
    272 long
    273 stol(const wstring& str, size_t* idx, int base)
    274 {
    275     return as_integer<long>( "stol", str, idx, base );
    276 }
    277 
    278 unsigned long
    279 stoul(const string& str, size_t* idx, int base)
    280 {
    281     return as_integer<unsigned long>( "stoul", str, idx, base );
    282 }
    283 
    284 unsigned long
    285 stoul(const wstring& str, size_t* idx, int base)
    286 {
    287     return as_integer<unsigned long>( "stoul", str, idx, base );
    288 }
    289 
    290 long long
    291 stoll(const string& str, size_t* idx, int base)
    292 {
    293     return as_integer<long long>( "stoll", str, idx, base );
    294 }
    295 
    296 long long
    297 stoll(const wstring& str, size_t* idx, int base)
    298 {
    299     return as_integer<long long>( "stoll", str, idx, base );
    300 }
    301 
    302 unsigned long long
    303 stoull(const string& str, size_t* idx, int base)
    304 {
    305     return as_integer<unsigned long long>( "stoull", str, idx, base );
    306 }
    307 
    308 unsigned long long
    309 stoull(const wstring& str, size_t* idx, int base)
    310 {
    311     return as_integer<unsigned long long>( "stoull", str, idx, base );
    312 }
    313 
    314 float
    315 stof(const string& str, size_t* idx)
    316 {
    317     return as_float<float>( "stof", str, idx );
    318 }
    319 
    320 float
    321 stof(const wstring& str, size_t* idx)
    322 {
    323     return as_float<float>( "stof", str, idx );
    324 }
    325 
    326 double
    327 stod(const string& str, size_t* idx)
    328 {
    329     return as_float<double>( "stod", str, idx );
    330 }
    331 
    332 double
    333 stod(const wstring& str, size_t* idx)
    334 {
    335     return as_float<double>( "stod", str, idx );
    336 }
    337 
    338 long double
    339 stold(const string& str, size_t* idx)
    340 {
    341     return as_float<long double>( "stold", str, idx );
    342 }
    343 
    344 long double
    345 stold(const wstring& str, size_t* idx)
    346 {
    347     return as_float<long double>( "stold", str, idx );
    348 }
    349 
    350 // to_string
    351 
    352 namespace
    353 {
    354 
    355 // as_string
    356 
    357 template<typename S, typename P, typename V >
    358 inline
    359 S
    360 as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a)
    361 {
    362     typedef typename S::size_type size_type;
    363     size_type available = s.size();
    364     while (true)
    365     {
    366         int status = sprintf_like(&s[0], available + 1, fmt, a);
    367         if ( status >= 0 )
    368         {
    369             size_type used = static_cast<size_type>(status);
    370             if ( used <= available )
    371             {
    372                 s.resize( used );
    373                 break;
    374             }
    375             available = used; // Assume this is advice of how much space we need.
    376         }
    377         else
    378             available = available * 2 + 1;
    379         s.resize(available);
    380     }
    381     return s;
    382 }
    383 
    384 template <class S, class V, bool = is_floating_point<V>::value>
    385 struct initial_string;
    386 
    387 template <class V, bool b>
    388 struct initial_string<string, V, b>
    389 {
    390     string
    391     operator()() const
    392     {
    393         string s;
    394         s.resize(s.capacity());
    395         return s;
    396     }
    397 };
    398 
    399 template <class V>
    400 struct initial_string<wstring, V, false>
    401 {
    402     wstring
    403     operator()() const
    404     {
    405         const size_t n = (numeric_limits<unsigned long long>::digits / 3)
    406           + ((numeric_limits<unsigned long long>::digits % 3) != 0)
    407           + 1;
    408         wstring s(n, wchar_t());
    409         s.resize(s.capacity());
    410         return s;
    411     }
    412 };
    413 
    414 template <class V>
    415 struct initial_string<wstring, V, true>
    416 {
    417     wstring
    418     operator()() const
    419     {
    420         wstring s(20, wchar_t());
    421         s.resize(s.capacity());
    422         return s;
    423     }
    424 };
    425 
    426 typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...);
    427 
    428 inline
    429 wide_printf
    430 get_swprintf()
    431 {
    432 #ifndef _LIBCPP_MSVCRT
    433     return swprintf;
    434 #else
    435     return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf);
    436 #endif
    437 }
    438 
    439 }  // unnamed namespace
    440 
    441 string to_string(int val)
    442 {
    443     return as_string(snprintf, initial_string<string, int>()(), "%d", val);
    444 }
    445 
    446 string to_string(unsigned val)
    447 {
    448     return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val);
    449 }
    450 
    451 string to_string(long val)
    452 {
    453     return as_string(snprintf, initial_string<string, long>()(), "%ld", val);
    454 }
    455 
    456 string to_string(unsigned long val)
    457 {
    458     return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val);
    459 }
    460 
    461 string to_string(long long val)
    462 {
    463     return as_string(snprintf, initial_string<string, long long>()(), "%lld", val);
    464 }
    465 
    466 string to_string(unsigned long long val)
    467 {
    468     return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val);
    469 }
    470 
    471 string to_string(float val)
    472 {
    473     return as_string(snprintf, initial_string<string, float>()(), "%f", val);
    474 }
    475 
    476 string to_string(double val)
    477 {
    478     return as_string(snprintf, initial_string<string, double>()(), "%f", val);
    479 }
    480 
    481 string to_string(long double val)
    482 {
    483     return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val);
    484 }
    485 
    486 wstring to_wstring(int val)
    487 {
    488     return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val);
    489 }
    490 
    491 wstring to_wstring(unsigned val)
    492 {
    493     return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val);
    494 }
    495 
    496 wstring to_wstring(long val)
    497 {
    498     return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val);
    499 }
    500 
    501 wstring to_wstring(unsigned long val)
    502 {
    503     return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val);
    504 }
    505 
    506 wstring to_wstring(long long val)
    507 {
    508     return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val);
    509 }
    510 
    511 wstring to_wstring(unsigned long long val)
    512 {
    513     return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val);
    514 }
    515 
    516 wstring to_wstring(float val)
    517 {
    518     return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val);
    519 }
    520 
    521 wstring to_wstring(double val)
    522 {
    523     return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val);
    524 }
    525 
    526 wstring to_wstring(long double val)
    527 {
    528     return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val);
    529 }
    530 _LIBCPP_END_NAMESPACE_STD
    531