1cbbf633eSHoward Hinnant //===------------------------- string.cpp ---------------------------------===// 2cbbf633eSHoward Hinnant // 3cbbf633eSHoward Hinnant // The LLVM Compiler Infrastructure 4cbbf633eSHoward Hinnant // 5412dbebeSHoward Hinnant // This file is dual licensed under the MIT and the University of Illinois Open 6412dbebeSHoward Hinnant // Source Licenses. See LICENSE.TXT for details. 7cbbf633eSHoward Hinnant // 8cbbf633eSHoward Hinnant //===----------------------------------------------------------------------===// 9cbbf633eSHoward Hinnant 10cbbf633eSHoward Hinnant #include "string" 11cbbf633eSHoward Hinnant #include "cstdlib" 12cbbf633eSHoward Hinnant #include "cwchar" 13cbbf633eSHoward Hinnant #include "cerrno" 149daaf577SHoward Hinnant #include "limits" 159daaf577SHoward Hinnant #include "stdexcept" 160be8f64cSHoward Hinnant #ifdef _LIBCPP_MSVCRT 17dbe81119SHoward Hinnant #include "support/win32/support.h" 180be8f64cSHoward Hinnant #endif // _LIBCPP_MSVCRT 191468d0ceSHoward Hinnant #include <stdio.h> 20cbbf633eSHoward Hinnant 21cbbf633eSHoward Hinnant _LIBCPP_BEGIN_NAMESPACE_STD 22cbbf633eSHoward Hinnant 23cbbf633eSHoward Hinnant template class __basic_string_common<true>; 24cbbf633eSHoward Hinnant 25cbbf633eSHoward Hinnant template class basic_string<char>; 26cbbf633eSHoward Hinnant template class basic_string<wchar_t>; 27cbbf633eSHoward Hinnant 28cbbf633eSHoward Hinnant template 29cbbf633eSHoward Hinnant string 30cbbf633eSHoward Hinnant operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); 31cbbf633eSHoward Hinnant 329daaf577SHoward Hinnant namespace 339daaf577SHoward Hinnant { 349daaf577SHoward Hinnant 359daaf577SHoward Hinnant template<typename T> 369daaf577SHoward Hinnant inline 379daaf577SHoward Hinnant void throw_helper( const string& msg ) 389daaf577SHoward Hinnant { 399daaf577SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS 409daaf577SHoward Hinnant throw T( msg ); 419daaf577SHoward Hinnant #else 42*c19393c7SEd Schouten fprintf(stderr, "%s\n", msg.c_str()); 439daaf577SHoward Hinnant abort(); 449daaf577SHoward Hinnant #endif 459daaf577SHoward Hinnant } 469daaf577SHoward Hinnant 479daaf577SHoward Hinnant inline 489daaf577SHoward Hinnant void throw_from_string_out_of_range( const string& func ) 499daaf577SHoward Hinnant { 509daaf577SHoward Hinnant throw_helper<out_of_range>(func + ": out of range"); 519daaf577SHoward Hinnant } 529daaf577SHoward Hinnant 539daaf577SHoward Hinnant inline 549daaf577SHoward Hinnant void throw_from_string_invalid_arg( const string& func ) 559daaf577SHoward Hinnant { 569daaf577SHoward Hinnant throw_helper<invalid_argument>(func + ": no conversion"); 579daaf577SHoward Hinnant } 589daaf577SHoward Hinnant 599daaf577SHoward Hinnant // as_integer 609daaf577SHoward Hinnant 619daaf577SHoward Hinnant template<typename V, typename S, typename F> 629daaf577SHoward Hinnant inline 639daaf577SHoward Hinnant V 649daaf577SHoward Hinnant as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) 659daaf577SHoward Hinnant { 66d6bd7bf6SEric Fiselier typename S::value_type* ptr = nullptr; 679daaf577SHoward Hinnant const typename S::value_type* const p = str.c_str(); 689daaf577SHoward Hinnant typename remove_reference<decltype(errno)>::type errno_save = errno; 699daaf577SHoward Hinnant errno = 0; 709daaf577SHoward Hinnant V r = f(p, &ptr, base); 719daaf577SHoward Hinnant swap(errno, errno_save); 729daaf577SHoward Hinnant if (errno_save == ERANGE) 739daaf577SHoward Hinnant throw_from_string_out_of_range(func); 749daaf577SHoward Hinnant if (ptr == p) 759daaf577SHoward Hinnant throw_from_string_invalid_arg(func); 769daaf577SHoward Hinnant if (idx) 779daaf577SHoward Hinnant *idx = static_cast<size_t>(ptr - p); 789daaf577SHoward Hinnant return r; 799daaf577SHoward Hinnant } 809daaf577SHoward Hinnant 819daaf577SHoward Hinnant template<typename V, typename S> 829daaf577SHoward Hinnant inline 839daaf577SHoward Hinnant V 849daaf577SHoward Hinnant as_integer(const string& func, const S& s, size_t* idx, int base); 859daaf577SHoward Hinnant 869daaf577SHoward Hinnant // string 879daaf577SHoward Hinnant template<> 889daaf577SHoward Hinnant inline 899daaf577SHoward Hinnant int 909daaf577SHoward Hinnant as_integer(const string& func, const string& s, size_t* idx, int base ) 919daaf577SHoward Hinnant { 928092c957SJoerg Sonnenberger // Use long as no Standard string to integer exists. 939daaf577SHoward Hinnant long r = as_integer_helper<long>( func, s, idx, base, strtol ); 949daaf577SHoward Hinnant if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 959daaf577SHoward Hinnant throw_from_string_out_of_range(func); 969daaf577SHoward Hinnant return static_cast<int>(r); 979daaf577SHoward Hinnant } 989daaf577SHoward Hinnant 999daaf577SHoward Hinnant template<> 1009daaf577SHoward Hinnant inline 1019daaf577SHoward Hinnant long 1029daaf577SHoward Hinnant as_integer(const string& func, const string& s, size_t* idx, int base ) 1039daaf577SHoward Hinnant { 1049daaf577SHoward Hinnant return as_integer_helper<long>( func, s, idx, base, strtol ); 1059daaf577SHoward Hinnant } 1069daaf577SHoward Hinnant 1079daaf577SHoward Hinnant template<> 1089daaf577SHoward Hinnant inline 1099daaf577SHoward Hinnant unsigned long 1109daaf577SHoward Hinnant as_integer( const string& func, const string& s, size_t* idx, int base ) 1119daaf577SHoward Hinnant { 1129daaf577SHoward Hinnant return as_integer_helper<unsigned long>( func, s, idx, base, strtoul ); 1139daaf577SHoward Hinnant } 1149daaf577SHoward Hinnant 1159daaf577SHoward Hinnant template<> 1169daaf577SHoward Hinnant inline 1179daaf577SHoward Hinnant long long 1189daaf577SHoward Hinnant as_integer( const string& func, const string& s, size_t* idx, int base ) 1199daaf577SHoward Hinnant { 1209daaf577SHoward Hinnant return as_integer_helper<long long>( func, s, idx, base, strtoll ); 1219daaf577SHoward Hinnant } 1229daaf577SHoward Hinnant 1239daaf577SHoward Hinnant template<> 1249daaf577SHoward Hinnant inline 1259daaf577SHoward Hinnant unsigned long long 1269daaf577SHoward Hinnant as_integer( const string& func, const string& s, size_t* idx, int base ) 1279daaf577SHoward Hinnant { 1289daaf577SHoward Hinnant return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull ); 1299daaf577SHoward Hinnant } 1309daaf577SHoward Hinnant 1319daaf577SHoward Hinnant // wstring 1329daaf577SHoward Hinnant template<> 1339daaf577SHoward Hinnant inline 1349daaf577SHoward Hinnant int 1359daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1369daaf577SHoward Hinnant { 1379daaf577SHoward Hinnant // Use long as no Stantard string to integer exists. 1389daaf577SHoward Hinnant long r = as_integer_helper<long>( func, s, idx, base, wcstol ); 1399daaf577SHoward Hinnant if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 1409daaf577SHoward Hinnant throw_from_string_out_of_range(func); 1419daaf577SHoward Hinnant return static_cast<int>(r); 1429daaf577SHoward Hinnant } 1439daaf577SHoward Hinnant 1449daaf577SHoward Hinnant template<> 1459daaf577SHoward Hinnant inline 1469daaf577SHoward Hinnant long 1479daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1489daaf577SHoward Hinnant { 1499daaf577SHoward Hinnant return as_integer_helper<long>( func, s, idx, base, wcstol ); 1509daaf577SHoward Hinnant } 1519daaf577SHoward Hinnant 1529daaf577SHoward Hinnant template<> 1539daaf577SHoward Hinnant inline 1549daaf577SHoward Hinnant unsigned long 1559daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1569daaf577SHoward Hinnant { 1579daaf577SHoward Hinnant return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul ); 1589daaf577SHoward Hinnant } 1599daaf577SHoward Hinnant 1609daaf577SHoward Hinnant template<> 1619daaf577SHoward Hinnant inline 1629daaf577SHoward Hinnant long long 1639daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1649daaf577SHoward Hinnant { 1659daaf577SHoward Hinnant return as_integer_helper<long long>( func, s, idx, base, wcstoll ); 1669daaf577SHoward Hinnant } 1679daaf577SHoward Hinnant 1689daaf577SHoward Hinnant template<> 1699daaf577SHoward Hinnant inline 1709daaf577SHoward Hinnant unsigned long long 1719daaf577SHoward Hinnant as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1729daaf577SHoward Hinnant { 1739daaf577SHoward Hinnant return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull ); 1749daaf577SHoward Hinnant } 1759daaf577SHoward Hinnant 1769daaf577SHoward Hinnant // as_float 1779daaf577SHoward Hinnant 1789daaf577SHoward Hinnant template<typename V, typename S, typename F> 1799daaf577SHoward Hinnant inline 1809daaf577SHoward Hinnant V 1819daaf577SHoward Hinnant as_float_helper(const string& func, const S& str, size_t* idx, F f ) 1829daaf577SHoward Hinnant { 183d6bd7bf6SEric Fiselier typename S::value_type* ptr = nullptr; 1849daaf577SHoward Hinnant const typename S::value_type* const p = str.c_str(); 1859daaf577SHoward Hinnant typename remove_reference<decltype(errno)>::type errno_save = errno; 1869daaf577SHoward Hinnant errno = 0; 1879daaf577SHoward Hinnant V r = f(p, &ptr); 1889daaf577SHoward Hinnant swap(errno, errno_save); 1899daaf577SHoward Hinnant if (errno_save == ERANGE) 1909daaf577SHoward Hinnant throw_from_string_out_of_range(func); 1919daaf577SHoward Hinnant if (ptr == p) 1929daaf577SHoward Hinnant throw_from_string_invalid_arg(func); 1939daaf577SHoward Hinnant if (idx) 1949daaf577SHoward Hinnant *idx = static_cast<size_t>(ptr - p); 1959daaf577SHoward Hinnant return r; 1969daaf577SHoward Hinnant } 1979daaf577SHoward Hinnant 1989daaf577SHoward Hinnant template<typename V, typename S> 1999daaf577SHoward Hinnant inline 2009daaf577SHoward Hinnant V as_float( const string& func, const S& s, size_t* idx = nullptr ); 2019daaf577SHoward Hinnant 2029daaf577SHoward Hinnant template<> 2039daaf577SHoward Hinnant inline 2049daaf577SHoward Hinnant float 2059daaf577SHoward Hinnant as_float( const string& func, const string& s, size_t* idx ) 2069daaf577SHoward Hinnant { 2079daaf577SHoward Hinnant return as_float_helper<float>( func, s, idx, strtof ); 2089daaf577SHoward Hinnant } 2099daaf577SHoward Hinnant 2109daaf577SHoward Hinnant template<> 2119daaf577SHoward Hinnant inline 2129daaf577SHoward Hinnant double 2139daaf577SHoward Hinnant as_float(const string& func, const string& s, size_t* idx ) 2149daaf577SHoward Hinnant { 2159daaf577SHoward Hinnant return as_float_helper<double>( func, s, idx, strtod ); 2169daaf577SHoward Hinnant } 2179daaf577SHoward Hinnant 2189daaf577SHoward Hinnant template<> 2199daaf577SHoward Hinnant inline 2209daaf577SHoward Hinnant long double 2219daaf577SHoward Hinnant as_float( const string& func, const string& s, size_t* idx ) 2229daaf577SHoward Hinnant { 2239daaf577SHoward Hinnant return as_float_helper<long double>( func, s, idx, strtold ); 2249daaf577SHoward Hinnant } 2259daaf577SHoward Hinnant 2269daaf577SHoward Hinnant template<> 2279daaf577SHoward Hinnant inline 2289daaf577SHoward Hinnant float 2299daaf577SHoward Hinnant as_float( const string& func, const wstring& s, size_t* idx ) 2309daaf577SHoward Hinnant { 2319daaf577SHoward Hinnant return as_float_helper<float>( func, s, idx, wcstof ); 2329daaf577SHoward Hinnant } 2339daaf577SHoward Hinnant 2349daaf577SHoward Hinnant template<> 2359daaf577SHoward Hinnant inline 2369daaf577SHoward Hinnant double 2379daaf577SHoward Hinnant as_float( const string& func, const wstring& s, size_t* idx ) 2389daaf577SHoward Hinnant { 2399daaf577SHoward Hinnant return as_float_helper<double>( func, s, idx, wcstod ); 2409daaf577SHoward Hinnant } 2419daaf577SHoward Hinnant 2429daaf577SHoward Hinnant template<> 2439daaf577SHoward Hinnant inline 2449daaf577SHoward Hinnant long double 2459daaf577SHoward Hinnant as_float( const string& func, const wstring& s, size_t* idx ) 2469daaf577SHoward Hinnant { 2479daaf577SHoward Hinnant return as_float_helper<long double>( func, s, idx, wcstold ); 2489daaf577SHoward Hinnant } 2499daaf577SHoward Hinnant 2509daaf577SHoward Hinnant } // unnamed namespace 2519daaf577SHoward Hinnant 252cbbf633eSHoward Hinnant int 253cbbf633eSHoward Hinnant stoi(const string& str, size_t* idx, int base) 254cbbf633eSHoward Hinnant { 2559daaf577SHoward Hinnant return as_integer<int>( "stoi", str, idx, base ); 256cbbf633eSHoward Hinnant } 257cbbf633eSHoward Hinnant 258cbbf633eSHoward Hinnant int 259cbbf633eSHoward Hinnant stoi(const wstring& str, size_t* idx, int base) 260cbbf633eSHoward Hinnant { 2619daaf577SHoward Hinnant return as_integer<int>( "stoi", str, idx, base ); 262cbbf633eSHoward Hinnant } 263cbbf633eSHoward Hinnant 264cbbf633eSHoward Hinnant long 265cbbf633eSHoward Hinnant stol(const string& str, size_t* idx, int base) 266cbbf633eSHoward Hinnant { 2679daaf577SHoward Hinnant return as_integer<long>( "stol", str, idx, base ); 268cbbf633eSHoward Hinnant } 269cbbf633eSHoward Hinnant 270cbbf633eSHoward Hinnant long 271cbbf633eSHoward Hinnant stol(const wstring& str, size_t* idx, int base) 272cbbf633eSHoward Hinnant { 2739daaf577SHoward Hinnant return as_integer<long>( "stol", str, idx, base ); 274cbbf633eSHoward Hinnant } 275cbbf633eSHoward Hinnant 276cbbf633eSHoward Hinnant unsigned long 277cbbf633eSHoward Hinnant stoul(const string& str, size_t* idx, int base) 278cbbf633eSHoward Hinnant { 2799daaf577SHoward Hinnant return as_integer<unsigned long>( "stoul", str, idx, base ); 280cbbf633eSHoward Hinnant } 281cbbf633eSHoward Hinnant 282cbbf633eSHoward Hinnant unsigned long 283cbbf633eSHoward Hinnant stoul(const wstring& str, size_t* idx, int base) 284cbbf633eSHoward Hinnant { 2859daaf577SHoward Hinnant return as_integer<unsigned long>( "stoul", str, idx, base ); 286cbbf633eSHoward Hinnant } 287cbbf633eSHoward Hinnant 288cbbf633eSHoward Hinnant long long 289cbbf633eSHoward Hinnant stoll(const string& str, size_t* idx, int base) 290cbbf633eSHoward Hinnant { 2919daaf577SHoward Hinnant return as_integer<long long>( "stoll", str, idx, base ); 292cbbf633eSHoward Hinnant } 293cbbf633eSHoward Hinnant 294cbbf633eSHoward Hinnant long long 295cbbf633eSHoward Hinnant stoll(const wstring& str, size_t* idx, int base) 296cbbf633eSHoward Hinnant { 2979daaf577SHoward Hinnant return as_integer<long long>( "stoll", str, idx, base ); 298cbbf633eSHoward Hinnant } 299cbbf633eSHoward Hinnant 300cbbf633eSHoward Hinnant unsigned long long 301cbbf633eSHoward Hinnant stoull(const string& str, size_t* idx, int base) 302cbbf633eSHoward Hinnant { 3039daaf577SHoward Hinnant return as_integer<unsigned long long>( "stoull", str, idx, base ); 304cbbf633eSHoward Hinnant } 305cbbf633eSHoward Hinnant 306cbbf633eSHoward Hinnant unsigned long long 307cbbf633eSHoward Hinnant stoull(const wstring& str, size_t* idx, int base) 308cbbf633eSHoward Hinnant { 3099daaf577SHoward Hinnant return as_integer<unsigned long long>( "stoull", str, idx, base ); 310cbbf633eSHoward Hinnant } 311cbbf633eSHoward Hinnant 312cbbf633eSHoward Hinnant float 313cbbf633eSHoward Hinnant stof(const string& str, size_t* idx) 314cbbf633eSHoward Hinnant { 3159daaf577SHoward Hinnant return as_float<float>( "stof", str, idx ); 316cbbf633eSHoward Hinnant } 317cbbf633eSHoward Hinnant 318cbbf633eSHoward Hinnant float 319cbbf633eSHoward Hinnant stof(const wstring& str, size_t* idx) 320cbbf633eSHoward Hinnant { 3219daaf577SHoward Hinnant return as_float<float>( "stof", str, idx ); 322cbbf633eSHoward Hinnant } 323cbbf633eSHoward Hinnant 324cbbf633eSHoward Hinnant double 325cbbf633eSHoward Hinnant stod(const string& str, size_t* idx) 326cbbf633eSHoward Hinnant { 3279daaf577SHoward Hinnant return as_float<double>( "stod", str, idx ); 328cbbf633eSHoward Hinnant } 329cbbf633eSHoward Hinnant 330cbbf633eSHoward Hinnant double 331cbbf633eSHoward Hinnant stod(const wstring& str, size_t* idx) 332cbbf633eSHoward Hinnant { 3339daaf577SHoward Hinnant return as_float<double>( "stod", str, idx ); 334cbbf633eSHoward Hinnant } 335cbbf633eSHoward Hinnant 336cbbf633eSHoward Hinnant long double 337cbbf633eSHoward Hinnant stold(const string& str, size_t* idx) 338cbbf633eSHoward Hinnant { 3399daaf577SHoward Hinnant return as_float<long double>( "stold", str, idx ); 340cbbf633eSHoward Hinnant } 341cbbf633eSHoward Hinnant 342cbbf633eSHoward Hinnant long double 343cbbf633eSHoward Hinnant stold(const wstring& str, size_t* idx) 344cbbf633eSHoward Hinnant { 3459daaf577SHoward Hinnant return as_float<long double>( "stold", str, idx ); 346cbbf633eSHoward Hinnant } 347cbbf633eSHoward Hinnant 3489daaf577SHoward Hinnant // to_string 3499daaf577SHoward Hinnant 3509daaf577SHoward Hinnant namespace 3519daaf577SHoward Hinnant { 3529daaf577SHoward Hinnant 3539daaf577SHoward Hinnant // as_string 3549daaf577SHoward Hinnant 3559daaf577SHoward Hinnant template<typename S, typename P, typename V > 3569daaf577SHoward Hinnant inline 3579daaf577SHoward Hinnant S 3589daaf577SHoward Hinnant as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a) 3599daaf577SHoward Hinnant { 3609daaf577SHoward Hinnant typedef typename S::size_type size_type; 3619daaf577SHoward Hinnant size_type available = s.size(); 3629daaf577SHoward Hinnant while (true) 3639daaf577SHoward Hinnant { 3649daaf577SHoward Hinnant int status = sprintf_like(&s[0], available + 1, fmt, a); 3659daaf577SHoward Hinnant if ( status >= 0 ) 3669daaf577SHoward Hinnant { 3679daaf577SHoward Hinnant size_type used = static_cast<size_type>(status); 3689daaf577SHoward Hinnant if ( used <= available ) 3699daaf577SHoward Hinnant { 3709daaf577SHoward Hinnant s.resize( used ); 3719daaf577SHoward Hinnant break; 3729daaf577SHoward Hinnant } 3739daaf577SHoward Hinnant available = used; // Assume this is advice of how much space we need. 3749daaf577SHoward Hinnant } 3759daaf577SHoward Hinnant else 3769daaf577SHoward Hinnant available = available * 2 + 1; 3779daaf577SHoward Hinnant s.resize(available); 3789daaf577SHoward Hinnant } 3799daaf577SHoward Hinnant return s; 3809daaf577SHoward Hinnant } 3819daaf577SHoward Hinnant 3829daaf577SHoward Hinnant template <class S, class V, bool = is_floating_point<V>::value> 3839daaf577SHoward Hinnant struct initial_string; 3849daaf577SHoward Hinnant 3859daaf577SHoward Hinnant template <class V, bool b> 3869daaf577SHoward Hinnant struct initial_string<string, V, b> 3879daaf577SHoward Hinnant { 3889daaf577SHoward Hinnant string 3899daaf577SHoward Hinnant operator()() const 390cbbf633eSHoward Hinnant { 391cbbf633eSHoward Hinnant string s; 392cbbf633eSHoward Hinnant s.resize(s.capacity()); 393cbbf633eSHoward Hinnant return s; 394cbbf633eSHoward Hinnant } 3959daaf577SHoward Hinnant }; 396cbbf633eSHoward Hinnant 3979daaf577SHoward Hinnant template <class V> 3989daaf577SHoward Hinnant struct initial_string<wstring, V, false> 399cbbf633eSHoward Hinnant { 4009daaf577SHoward Hinnant wstring 4019daaf577SHoward Hinnant operator()() const 402cbbf633eSHoward Hinnant { 403cbbf633eSHoward Hinnant const size_t n = (numeric_limits<unsigned long long>::digits / 3) 404cbbf633eSHoward Hinnant + ((numeric_limits<unsigned long long>::digits % 3) != 0) 405cbbf633eSHoward Hinnant + 1; 406cbbf633eSHoward Hinnant wstring s(n, wchar_t()); 407cbbf633eSHoward Hinnant s.resize(s.capacity()); 408cbbf633eSHoward Hinnant return s; 409cbbf633eSHoward Hinnant } 4109daaf577SHoward Hinnant }; 4119daaf577SHoward Hinnant 4129daaf577SHoward Hinnant template <class V> 4139daaf577SHoward Hinnant struct initial_string<wstring, V, true> 4149daaf577SHoward Hinnant { 4159daaf577SHoward Hinnant wstring 4169daaf577SHoward Hinnant operator()() const 4179daaf577SHoward Hinnant { 4189daaf577SHoward Hinnant wstring s(20, wchar_t()); 4199daaf577SHoward Hinnant s.resize(s.capacity()); 4209daaf577SHoward Hinnant return s; 4219daaf577SHoward Hinnant } 4229daaf577SHoward Hinnant }; 4239daaf577SHoward Hinnant 4249daaf577SHoward Hinnant typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); 4259daaf577SHoward Hinnant 4269daaf577SHoward Hinnant inline 4279daaf577SHoward Hinnant wide_printf 4289daaf577SHoward Hinnant get_swprintf() 4299daaf577SHoward Hinnant { 4300be8f64cSHoward Hinnant #ifndef _LIBCPP_MSVCRT 4319daaf577SHoward Hinnant return swprintf; 4329daaf577SHoward Hinnant #else 4339daaf577SHoward Hinnant return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf); 4349daaf577SHoward Hinnant #endif 4359daaf577SHoward Hinnant } 4369daaf577SHoward Hinnant 4379daaf577SHoward Hinnant } // unnamed namespace 4389daaf577SHoward Hinnant 4399daaf577SHoward Hinnant string to_string(int val) 4409daaf577SHoward Hinnant { 4419daaf577SHoward Hinnant return as_string(snprintf, initial_string<string, int>()(), "%d", val); 4429daaf577SHoward Hinnant } 4439daaf577SHoward Hinnant 4449daaf577SHoward Hinnant string to_string(unsigned val) 4459daaf577SHoward Hinnant { 4469daaf577SHoward Hinnant return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val); 4479daaf577SHoward Hinnant } 4489daaf577SHoward Hinnant 4499daaf577SHoward Hinnant string to_string(long val) 4509daaf577SHoward Hinnant { 4519daaf577SHoward Hinnant return as_string(snprintf, initial_string<string, long>()(), "%ld", val); 4529daaf577SHoward Hinnant } 4539daaf577SHoward Hinnant 4549daaf577SHoward Hinnant string to_string(unsigned long val) 4559daaf577SHoward Hinnant { 4569daaf577SHoward Hinnant return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val); 4579daaf577SHoward Hinnant } 4589daaf577SHoward Hinnant 4599daaf577SHoward Hinnant string to_string(long long val) 4609daaf577SHoward Hinnant { 4619daaf577SHoward Hinnant return as_string(snprintf, initial_string<string, long long>()(), "%lld", val); 4629daaf577SHoward Hinnant } 4639daaf577SHoward Hinnant 4649daaf577SHoward Hinnant string to_string(unsigned long long val) 4659daaf577SHoward Hinnant { 4669daaf577SHoward Hinnant return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val); 4679daaf577SHoward Hinnant } 4689daaf577SHoward Hinnant 4699daaf577SHoward Hinnant string to_string(float val) 4709daaf577SHoward Hinnant { 4719daaf577SHoward Hinnant return as_string(snprintf, initial_string<string, float>()(), "%f", val); 4729daaf577SHoward Hinnant } 4739daaf577SHoward Hinnant 4749daaf577SHoward Hinnant string to_string(double val) 4759daaf577SHoward Hinnant { 4769daaf577SHoward Hinnant return as_string(snprintf, initial_string<string, double>()(), "%f", val); 4779daaf577SHoward Hinnant } 4789daaf577SHoward Hinnant 4799daaf577SHoward Hinnant string to_string(long double val) 4809daaf577SHoward Hinnant { 4819daaf577SHoward Hinnant return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val); 4829daaf577SHoward Hinnant } 4839daaf577SHoward Hinnant 4849daaf577SHoward Hinnant wstring to_wstring(int val) 4859daaf577SHoward Hinnant { 4869daaf577SHoward Hinnant return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val); 4879daaf577SHoward Hinnant } 4889daaf577SHoward Hinnant 4899daaf577SHoward Hinnant wstring to_wstring(unsigned val) 4909daaf577SHoward Hinnant { 4919daaf577SHoward Hinnant return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val); 4929daaf577SHoward Hinnant } 4939daaf577SHoward Hinnant 4949daaf577SHoward Hinnant wstring to_wstring(long val) 4959daaf577SHoward Hinnant { 4969daaf577SHoward Hinnant return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val); 4979daaf577SHoward Hinnant } 4989daaf577SHoward Hinnant 4999daaf577SHoward Hinnant wstring to_wstring(unsigned long val) 5009daaf577SHoward Hinnant { 5019daaf577SHoward Hinnant return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val); 5029daaf577SHoward Hinnant } 5039daaf577SHoward Hinnant 5049daaf577SHoward Hinnant wstring to_wstring(long long val) 5059daaf577SHoward Hinnant { 5069daaf577SHoward Hinnant return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val); 5079daaf577SHoward Hinnant } 5089daaf577SHoward Hinnant 5099daaf577SHoward Hinnant wstring to_wstring(unsigned long long val) 5109daaf577SHoward Hinnant { 5119daaf577SHoward Hinnant return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val); 5129daaf577SHoward Hinnant } 513cbbf633eSHoward Hinnant 514cbbf633eSHoward Hinnant wstring to_wstring(float val) 515cbbf633eSHoward Hinnant { 5169daaf577SHoward Hinnant return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val); 517cbbf633eSHoward Hinnant } 518cbbf633eSHoward Hinnant 519cbbf633eSHoward Hinnant wstring to_wstring(double val) 520cbbf633eSHoward Hinnant { 5219daaf577SHoward Hinnant return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val); 522cbbf633eSHoward Hinnant } 523cbbf633eSHoward Hinnant 524cbbf633eSHoward Hinnant wstring to_wstring(long double val) 525cbbf633eSHoward Hinnant { 5269daaf577SHoward Hinnant return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val); 527cbbf633eSHoward Hinnant } 528cbbf633eSHoward Hinnant _LIBCPP_END_NAMESPACE_STD 529