17a984708SDavid Chisnall //===------------------------- string.cpp ---------------------------------===// 27a984708SDavid Chisnall // 37a984708SDavid Chisnall // The LLVM Compiler Infrastructure 47a984708SDavid Chisnall // 57a984708SDavid Chisnall // This file is dual licensed under the MIT and the University of Illinois Open 67a984708SDavid Chisnall // Source Licenses. See LICENSE.TXT for details. 77a984708SDavid Chisnall // 87a984708SDavid Chisnall //===----------------------------------------------------------------------===// 97a984708SDavid Chisnall 107a984708SDavid Chisnall #include "string" 117a984708SDavid Chisnall #include "cstdlib" 127a984708SDavid Chisnall #include "cwchar" 137a984708SDavid Chisnall #include "cerrno" 144bab9fd9SDavid Chisnall #include "limits" 154bab9fd9SDavid Chisnall #include "stdexcept" 164f7ab58eSDimitry Andric #ifdef _LIBCPP_MSVCRT 177a984708SDavid Chisnall #include "support/win32/support.h" 184f7ab58eSDimitry Andric #endif // _LIBCPP_MSVCRT 194f7ab58eSDimitry Andric #include <stdio.h> 207a984708SDavid Chisnall 217a984708SDavid Chisnall _LIBCPP_BEGIN_NAMESPACE_STD 227a984708SDavid Chisnall 23*aed8d94eSDimitry Andric template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common<true>; 247a984708SDavid Chisnall 25*aed8d94eSDimitry Andric template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<char>; 26*aed8d94eSDimitry Andric template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<wchar_t>; 277a984708SDavid Chisnall 287a984708SDavid Chisnall template 297a984708SDavid Chisnall string 307a984708SDavid Chisnall operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); 317a984708SDavid Chisnall 324bab9fd9SDavid Chisnall namespace 334bab9fd9SDavid Chisnall { 344bab9fd9SDavid Chisnall 354bab9fd9SDavid Chisnall template<typename T> 364bab9fd9SDavid Chisnall inline 374bab9fd9SDavid Chisnall void throw_helper( const string& msg ) 384bab9fd9SDavid Chisnall { 394bab9fd9SDavid Chisnall #ifndef _LIBCPP_NO_EXCEPTIONS 404bab9fd9SDavid Chisnall throw T( msg ); 414bab9fd9SDavid Chisnall #else 42854fa44bSDimitry Andric fprintf(stderr, "%s\n", msg.c_str()); 43*aed8d94eSDimitry Andric _VSTD::abort(); 444bab9fd9SDavid Chisnall #endif 454bab9fd9SDavid Chisnall } 464bab9fd9SDavid Chisnall 474bab9fd9SDavid Chisnall inline 484bab9fd9SDavid Chisnall void throw_from_string_out_of_range( const string& func ) 494bab9fd9SDavid Chisnall { 504bab9fd9SDavid Chisnall throw_helper<out_of_range>(func + ": out of range"); 514bab9fd9SDavid Chisnall } 524bab9fd9SDavid Chisnall 534bab9fd9SDavid Chisnall inline 544bab9fd9SDavid Chisnall void throw_from_string_invalid_arg( const string& func ) 554bab9fd9SDavid Chisnall { 564bab9fd9SDavid Chisnall throw_helper<invalid_argument>(func + ": no conversion"); 574bab9fd9SDavid Chisnall } 584bab9fd9SDavid Chisnall 594bab9fd9SDavid Chisnall // as_integer 604bab9fd9SDavid Chisnall 614bab9fd9SDavid Chisnall template<typename V, typename S, typename F> 624bab9fd9SDavid Chisnall inline 634bab9fd9SDavid Chisnall V 644bab9fd9SDavid Chisnall as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) 654bab9fd9SDavid Chisnall { 66d72607e9SDimitry Andric typename S::value_type* ptr = nullptr; 674bab9fd9SDavid Chisnall const typename S::value_type* const p = str.c_str(); 684bab9fd9SDavid Chisnall typename remove_reference<decltype(errno)>::type errno_save = errno; 694bab9fd9SDavid Chisnall errno = 0; 704bab9fd9SDavid Chisnall V r = f(p, &ptr, base); 714bab9fd9SDavid Chisnall swap(errno, errno_save); 724bab9fd9SDavid Chisnall if (errno_save == ERANGE) 734bab9fd9SDavid Chisnall throw_from_string_out_of_range(func); 744bab9fd9SDavid Chisnall if (ptr == p) 754bab9fd9SDavid Chisnall throw_from_string_invalid_arg(func); 764bab9fd9SDavid Chisnall if (idx) 774bab9fd9SDavid Chisnall *idx = static_cast<size_t>(ptr - p); 784bab9fd9SDavid Chisnall return r; 794bab9fd9SDavid Chisnall } 804bab9fd9SDavid Chisnall 814bab9fd9SDavid Chisnall template<typename V, typename S> 824bab9fd9SDavid Chisnall inline 834bab9fd9SDavid Chisnall V 844bab9fd9SDavid Chisnall as_integer(const string& func, const S& s, size_t* idx, int base); 854bab9fd9SDavid Chisnall 864bab9fd9SDavid Chisnall // string 874bab9fd9SDavid Chisnall template<> 884bab9fd9SDavid Chisnall inline 894bab9fd9SDavid Chisnall int 904bab9fd9SDavid Chisnall as_integer(const string& func, const string& s, size_t* idx, int base ) 914bab9fd9SDavid Chisnall { 924f7ab58eSDimitry Andric // Use long as no Standard string to integer exists. 934bab9fd9SDavid Chisnall long r = as_integer_helper<long>( func, s, idx, base, strtol ); 944bab9fd9SDavid Chisnall if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 954bab9fd9SDavid Chisnall throw_from_string_out_of_range(func); 964bab9fd9SDavid Chisnall return static_cast<int>(r); 974bab9fd9SDavid Chisnall } 984bab9fd9SDavid Chisnall 994bab9fd9SDavid Chisnall template<> 1004bab9fd9SDavid Chisnall inline 1014bab9fd9SDavid Chisnall long 1024bab9fd9SDavid Chisnall as_integer(const string& func, const string& s, size_t* idx, int base ) 1034bab9fd9SDavid Chisnall { 1044bab9fd9SDavid Chisnall return as_integer_helper<long>( func, s, idx, base, strtol ); 1054bab9fd9SDavid Chisnall } 1064bab9fd9SDavid Chisnall 1074bab9fd9SDavid Chisnall template<> 1084bab9fd9SDavid Chisnall inline 1094bab9fd9SDavid Chisnall unsigned long 1104bab9fd9SDavid Chisnall as_integer( const string& func, const string& s, size_t* idx, int base ) 1114bab9fd9SDavid Chisnall { 1124bab9fd9SDavid Chisnall return as_integer_helper<unsigned long>( func, s, idx, base, strtoul ); 1134bab9fd9SDavid Chisnall } 1144bab9fd9SDavid Chisnall 1154bab9fd9SDavid Chisnall template<> 1164bab9fd9SDavid Chisnall inline 1174bab9fd9SDavid Chisnall long long 1184bab9fd9SDavid Chisnall as_integer( const string& func, const string& s, size_t* idx, int base ) 1194bab9fd9SDavid Chisnall { 1204bab9fd9SDavid Chisnall return as_integer_helper<long long>( func, s, idx, base, strtoll ); 1214bab9fd9SDavid Chisnall } 1224bab9fd9SDavid Chisnall 1234bab9fd9SDavid Chisnall template<> 1244bab9fd9SDavid Chisnall inline 1254bab9fd9SDavid Chisnall unsigned long long 1264bab9fd9SDavid Chisnall as_integer( const string& func, const string& s, size_t* idx, int base ) 1274bab9fd9SDavid Chisnall { 1284bab9fd9SDavid Chisnall return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull ); 1294bab9fd9SDavid Chisnall } 1304bab9fd9SDavid Chisnall 1314bab9fd9SDavid Chisnall // wstring 1324bab9fd9SDavid Chisnall template<> 1334bab9fd9SDavid Chisnall inline 1344bab9fd9SDavid Chisnall int 1354bab9fd9SDavid Chisnall as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1364bab9fd9SDavid Chisnall { 1374bab9fd9SDavid Chisnall // Use long as no Stantard string to integer exists. 1384bab9fd9SDavid Chisnall long r = as_integer_helper<long>( func, s, idx, base, wcstol ); 1394bab9fd9SDavid Chisnall if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 1404bab9fd9SDavid Chisnall throw_from_string_out_of_range(func); 1414bab9fd9SDavid Chisnall return static_cast<int>(r); 1424bab9fd9SDavid Chisnall } 1434bab9fd9SDavid Chisnall 1444bab9fd9SDavid Chisnall template<> 1454bab9fd9SDavid Chisnall inline 1464bab9fd9SDavid Chisnall long 1474bab9fd9SDavid Chisnall as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1484bab9fd9SDavid Chisnall { 1494bab9fd9SDavid Chisnall return as_integer_helper<long>( func, s, idx, base, wcstol ); 1504bab9fd9SDavid Chisnall } 1514bab9fd9SDavid Chisnall 1524bab9fd9SDavid Chisnall template<> 1534bab9fd9SDavid Chisnall inline 1544bab9fd9SDavid Chisnall unsigned long 1554bab9fd9SDavid Chisnall as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1564bab9fd9SDavid Chisnall { 1574bab9fd9SDavid Chisnall return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul ); 1584bab9fd9SDavid Chisnall } 1594bab9fd9SDavid Chisnall 1604bab9fd9SDavid Chisnall template<> 1614bab9fd9SDavid Chisnall inline 1624bab9fd9SDavid Chisnall long long 1634bab9fd9SDavid Chisnall as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1644bab9fd9SDavid Chisnall { 1654bab9fd9SDavid Chisnall return as_integer_helper<long long>( func, s, idx, base, wcstoll ); 1664bab9fd9SDavid Chisnall } 1674bab9fd9SDavid Chisnall 1684bab9fd9SDavid Chisnall template<> 1694bab9fd9SDavid Chisnall inline 1704bab9fd9SDavid Chisnall unsigned long long 1714bab9fd9SDavid Chisnall as_integer( const string& func, const wstring& s, size_t* idx, int base ) 1724bab9fd9SDavid Chisnall { 1734bab9fd9SDavid Chisnall return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull ); 1744bab9fd9SDavid Chisnall } 1754bab9fd9SDavid Chisnall 1764bab9fd9SDavid Chisnall // as_float 1774bab9fd9SDavid Chisnall 1784bab9fd9SDavid Chisnall template<typename V, typename S, typename F> 1794bab9fd9SDavid Chisnall inline 1804bab9fd9SDavid Chisnall V 1814bab9fd9SDavid Chisnall as_float_helper(const string& func, const S& str, size_t* idx, F f ) 1824bab9fd9SDavid Chisnall { 183d72607e9SDimitry Andric typename S::value_type* ptr = nullptr; 1844bab9fd9SDavid Chisnall const typename S::value_type* const p = str.c_str(); 1854bab9fd9SDavid Chisnall typename remove_reference<decltype(errno)>::type errno_save = errno; 1864bab9fd9SDavid Chisnall errno = 0; 1874bab9fd9SDavid Chisnall V r = f(p, &ptr); 1884bab9fd9SDavid Chisnall swap(errno, errno_save); 1894bab9fd9SDavid Chisnall if (errno_save == ERANGE) 1904bab9fd9SDavid Chisnall throw_from_string_out_of_range(func); 1914bab9fd9SDavid Chisnall if (ptr == p) 1924bab9fd9SDavid Chisnall throw_from_string_invalid_arg(func); 1934bab9fd9SDavid Chisnall if (idx) 1944bab9fd9SDavid Chisnall *idx = static_cast<size_t>(ptr - p); 1954bab9fd9SDavid Chisnall return r; 1964bab9fd9SDavid Chisnall } 1974bab9fd9SDavid Chisnall 1984bab9fd9SDavid Chisnall template<typename V, typename S> 1994bab9fd9SDavid Chisnall inline 2004bab9fd9SDavid Chisnall V as_float( const string& func, const S& s, size_t* idx = nullptr ); 2014bab9fd9SDavid Chisnall 2024bab9fd9SDavid Chisnall template<> 2034bab9fd9SDavid Chisnall inline 2044bab9fd9SDavid Chisnall float 2054bab9fd9SDavid Chisnall as_float( const string& func, const string& s, size_t* idx ) 2064bab9fd9SDavid Chisnall { 2074bab9fd9SDavid Chisnall return as_float_helper<float>( func, s, idx, strtof ); 2084bab9fd9SDavid Chisnall } 2094bab9fd9SDavid Chisnall 2104bab9fd9SDavid Chisnall template<> 2114bab9fd9SDavid Chisnall inline 2124bab9fd9SDavid Chisnall double 2134bab9fd9SDavid Chisnall as_float(const string& func, const string& s, size_t* idx ) 2144bab9fd9SDavid Chisnall { 2154bab9fd9SDavid Chisnall return as_float_helper<double>( func, s, idx, strtod ); 2164bab9fd9SDavid Chisnall } 2174bab9fd9SDavid Chisnall 2184bab9fd9SDavid Chisnall template<> 2194bab9fd9SDavid Chisnall inline 2204bab9fd9SDavid Chisnall long double 2214bab9fd9SDavid Chisnall as_float( const string& func, const string& s, size_t* idx ) 2224bab9fd9SDavid Chisnall { 2234bab9fd9SDavid Chisnall return as_float_helper<long double>( func, s, idx, strtold ); 2244bab9fd9SDavid Chisnall } 2254bab9fd9SDavid Chisnall 2264bab9fd9SDavid Chisnall template<> 2274bab9fd9SDavid Chisnall inline 2284bab9fd9SDavid Chisnall float 2294bab9fd9SDavid Chisnall as_float( const string& func, const wstring& s, size_t* idx ) 2304bab9fd9SDavid Chisnall { 2314bab9fd9SDavid Chisnall return as_float_helper<float>( func, s, idx, wcstof ); 2324bab9fd9SDavid Chisnall } 2334bab9fd9SDavid Chisnall 2344bab9fd9SDavid Chisnall template<> 2354bab9fd9SDavid Chisnall inline 2364bab9fd9SDavid Chisnall double 2374bab9fd9SDavid Chisnall as_float( const string& func, const wstring& s, size_t* idx ) 2384bab9fd9SDavid Chisnall { 2394bab9fd9SDavid Chisnall return as_float_helper<double>( func, s, idx, wcstod ); 2404bab9fd9SDavid Chisnall } 2414bab9fd9SDavid Chisnall 2424bab9fd9SDavid Chisnall template<> 2434bab9fd9SDavid Chisnall inline 2444bab9fd9SDavid Chisnall long double 2454bab9fd9SDavid Chisnall as_float( const string& func, const wstring& s, size_t* idx ) 2464bab9fd9SDavid Chisnall { 2474bab9fd9SDavid Chisnall return as_float_helper<long double>( func, s, idx, wcstold ); 2484bab9fd9SDavid Chisnall } 2494bab9fd9SDavid Chisnall 2504bab9fd9SDavid Chisnall } // unnamed namespace 2514bab9fd9SDavid Chisnall 2527a984708SDavid Chisnall int 2537a984708SDavid Chisnall stoi(const string& str, size_t* idx, int base) 2547a984708SDavid Chisnall { 2554bab9fd9SDavid Chisnall return as_integer<int>( "stoi", str, idx, base ); 2567a984708SDavid Chisnall } 2577a984708SDavid Chisnall 2587a984708SDavid Chisnall int 2597a984708SDavid Chisnall stoi(const wstring& str, size_t* idx, int base) 2607a984708SDavid Chisnall { 2614bab9fd9SDavid Chisnall return as_integer<int>( "stoi", str, idx, base ); 2627a984708SDavid Chisnall } 2637a984708SDavid Chisnall 2647a984708SDavid Chisnall long 2657a984708SDavid Chisnall stol(const string& str, size_t* idx, int base) 2667a984708SDavid Chisnall { 2674bab9fd9SDavid Chisnall return as_integer<long>( "stol", str, idx, base ); 2687a984708SDavid Chisnall } 2697a984708SDavid Chisnall 2707a984708SDavid Chisnall long 2717a984708SDavid Chisnall stol(const wstring& str, size_t* idx, int base) 2727a984708SDavid Chisnall { 2734bab9fd9SDavid Chisnall return as_integer<long>( "stol", str, idx, base ); 2747a984708SDavid Chisnall } 2757a984708SDavid Chisnall 2767a984708SDavid Chisnall unsigned long 2777a984708SDavid Chisnall stoul(const string& str, size_t* idx, int base) 2787a984708SDavid Chisnall { 2794bab9fd9SDavid Chisnall return as_integer<unsigned long>( "stoul", str, idx, base ); 2807a984708SDavid Chisnall } 2817a984708SDavid Chisnall 2827a984708SDavid Chisnall unsigned long 2837a984708SDavid Chisnall stoul(const wstring& str, size_t* idx, int base) 2847a984708SDavid Chisnall { 2854bab9fd9SDavid Chisnall return as_integer<unsigned long>( "stoul", str, idx, base ); 2867a984708SDavid Chisnall } 2877a984708SDavid Chisnall 2887a984708SDavid Chisnall long long 2897a984708SDavid Chisnall stoll(const string& str, size_t* idx, int base) 2907a984708SDavid Chisnall { 2914bab9fd9SDavid Chisnall return as_integer<long long>( "stoll", str, idx, base ); 2927a984708SDavid Chisnall } 2937a984708SDavid Chisnall 2947a984708SDavid Chisnall long long 2957a984708SDavid Chisnall stoll(const wstring& str, size_t* idx, int base) 2967a984708SDavid Chisnall { 2974bab9fd9SDavid Chisnall return as_integer<long long>( "stoll", str, idx, base ); 2987a984708SDavid Chisnall } 2997a984708SDavid Chisnall 3007a984708SDavid Chisnall unsigned long long 3017a984708SDavid Chisnall stoull(const string& str, size_t* idx, int base) 3027a984708SDavid Chisnall { 3034bab9fd9SDavid Chisnall return as_integer<unsigned long long>( "stoull", str, idx, base ); 3047a984708SDavid Chisnall } 3057a984708SDavid Chisnall 3067a984708SDavid Chisnall unsigned long long 3077a984708SDavid Chisnall stoull(const wstring& str, size_t* idx, int base) 3087a984708SDavid Chisnall { 3094bab9fd9SDavid Chisnall return as_integer<unsigned long long>( "stoull", str, idx, base ); 3107a984708SDavid Chisnall } 3117a984708SDavid Chisnall 3127a984708SDavid Chisnall float 3137a984708SDavid Chisnall stof(const string& str, size_t* idx) 3147a984708SDavid Chisnall { 3154bab9fd9SDavid Chisnall return as_float<float>( "stof", str, idx ); 3167a984708SDavid Chisnall } 3177a984708SDavid Chisnall 3187a984708SDavid Chisnall float 3197a984708SDavid Chisnall stof(const wstring& str, size_t* idx) 3207a984708SDavid Chisnall { 3214bab9fd9SDavid Chisnall return as_float<float>( "stof", str, idx ); 3227a984708SDavid Chisnall } 3237a984708SDavid Chisnall 3247a984708SDavid Chisnall double 3257a984708SDavid Chisnall stod(const string& str, size_t* idx) 3267a984708SDavid Chisnall { 3274bab9fd9SDavid Chisnall return as_float<double>( "stod", str, idx ); 3287a984708SDavid Chisnall } 3297a984708SDavid Chisnall 3307a984708SDavid Chisnall double 3317a984708SDavid Chisnall stod(const wstring& str, size_t* idx) 3327a984708SDavid Chisnall { 3334bab9fd9SDavid Chisnall return as_float<double>( "stod", str, idx ); 3347a984708SDavid Chisnall } 3357a984708SDavid Chisnall 3367a984708SDavid Chisnall long double 3377a984708SDavid Chisnall stold(const string& str, size_t* idx) 3387a984708SDavid Chisnall { 3394bab9fd9SDavid Chisnall return as_float<long double>( "stold", str, idx ); 3407a984708SDavid Chisnall } 3417a984708SDavid Chisnall 3427a984708SDavid Chisnall long double 3437a984708SDavid Chisnall stold(const wstring& str, size_t* idx) 3447a984708SDavid Chisnall { 3454bab9fd9SDavid Chisnall return as_float<long double>( "stold", str, idx ); 3467a984708SDavid Chisnall } 3477a984708SDavid Chisnall 3484bab9fd9SDavid Chisnall // to_string 3494bab9fd9SDavid Chisnall 3504bab9fd9SDavid Chisnall namespace 3514bab9fd9SDavid Chisnall { 3524bab9fd9SDavid Chisnall 3534bab9fd9SDavid Chisnall // as_string 3544bab9fd9SDavid Chisnall 3554bab9fd9SDavid Chisnall template<typename S, typename P, typename V > 3564bab9fd9SDavid Chisnall inline 3574bab9fd9SDavid Chisnall S 3584bab9fd9SDavid Chisnall as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a) 3594bab9fd9SDavid Chisnall { 3604bab9fd9SDavid Chisnall typedef typename S::size_type size_type; 3614bab9fd9SDavid Chisnall size_type available = s.size(); 3624bab9fd9SDavid Chisnall while (true) 3634bab9fd9SDavid Chisnall { 3644bab9fd9SDavid Chisnall int status = sprintf_like(&s[0], available + 1, fmt, a); 3654bab9fd9SDavid Chisnall if ( status >= 0 ) 3664bab9fd9SDavid Chisnall { 3674bab9fd9SDavid Chisnall size_type used = static_cast<size_type>(status); 3684bab9fd9SDavid Chisnall if ( used <= available ) 3694bab9fd9SDavid Chisnall { 3704bab9fd9SDavid Chisnall s.resize( used ); 3714bab9fd9SDavid Chisnall break; 3724bab9fd9SDavid Chisnall } 3734bab9fd9SDavid Chisnall available = used; // Assume this is advice of how much space we need. 3744bab9fd9SDavid Chisnall } 3754bab9fd9SDavid Chisnall else 3764bab9fd9SDavid Chisnall available = available * 2 + 1; 3774bab9fd9SDavid Chisnall s.resize(available); 3784bab9fd9SDavid Chisnall } 3794bab9fd9SDavid Chisnall return s; 3804bab9fd9SDavid Chisnall } 3814bab9fd9SDavid Chisnall 3824bab9fd9SDavid Chisnall template <class S, class V, bool = is_floating_point<V>::value> 3834bab9fd9SDavid Chisnall struct initial_string; 3844bab9fd9SDavid Chisnall 3854bab9fd9SDavid Chisnall template <class V, bool b> 3864bab9fd9SDavid Chisnall struct initial_string<string, V, b> 3874bab9fd9SDavid Chisnall { 3884bab9fd9SDavid Chisnall string 3894bab9fd9SDavid Chisnall operator()() const 3907a984708SDavid Chisnall { 3917a984708SDavid Chisnall string s; 3927a984708SDavid Chisnall s.resize(s.capacity()); 3937a984708SDavid Chisnall return s; 3947a984708SDavid Chisnall } 3954bab9fd9SDavid Chisnall }; 3967a984708SDavid Chisnall 3974bab9fd9SDavid Chisnall template <class V> 3984bab9fd9SDavid Chisnall struct initial_string<wstring, V, false> 3997a984708SDavid Chisnall { 4004bab9fd9SDavid Chisnall wstring 4014bab9fd9SDavid Chisnall operator()() const 4027a984708SDavid Chisnall { 4037a984708SDavid Chisnall const size_t n = (numeric_limits<unsigned long long>::digits / 3) 4047a984708SDavid Chisnall + ((numeric_limits<unsigned long long>::digits % 3) != 0) 4057a984708SDavid Chisnall + 1; 4067a984708SDavid Chisnall wstring s(n, wchar_t()); 4077a984708SDavid Chisnall s.resize(s.capacity()); 4087a984708SDavid Chisnall return s; 4097a984708SDavid Chisnall } 4104bab9fd9SDavid Chisnall }; 4114bab9fd9SDavid Chisnall 4124bab9fd9SDavid Chisnall template <class V> 4134bab9fd9SDavid Chisnall struct initial_string<wstring, V, true> 4144bab9fd9SDavid Chisnall { 4154bab9fd9SDavid Chisnall wstring 4164bab9fd9SDavid Chisnall operator()() const 4174bab9fd9SDavid Chisnall { 4184bab9fd9SDavid Chisnall wstring s(20, wchar_t()); 4194bab9fd9SDavid Chisnall s.resize(s.capacity()); 4204bab9fd9SDavid Chisnall return s; 4214bab9fd9SDavid Chisnall } 4224bab9fd9SDavid Chisnall }; 4234bab9fd9SDavid Chisnall 4244bab9fd9SDavid Chisnall typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); 4254bab9fd9SDavid Chisnall 4264bab9fd9SDavid Chisnall inline 4274bab9fd9SDavid Chisnall wide_printf 4284bab9fd9SDavid Chisnall get_swprintf() 4294bab9fd9SDavid Chisnall { 4304f7ab58eSDimitry Andric #ifndef _LIBCPP_MSVCRT 4314bab9fd9SDavid Chisnall return swprintf; 4324bab9fd9SDavid Chisnall #else 4334bab9fd9SDavid Chisnall return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf); 4344bab9fd9SDavid Chisnall #endif 4354bab9fd9SDavid Chisnall } 4364bab9fd9SDavid Chisnall 4374bab9fd9SDavid Chisnall } // unnamed namespace 4384bab9fd9SDavid Chisnall 4394bab9fd9SDavid Chisnall string to_string(int val) 4404bab9fd9SDavid Chisnall { 4414bab9fd9SDavid Chisnall return as_string(snprintf, initial_string<string, int>()(), "%d", val); 4424bab9fd9SDavid Chisnall } 4434bab9fd9SDavid Chisnall 4444bab9fd9SDavid Chisnall string to_string(unsigned val) 4454bab9fd9SDavid Chisnall { 4464bab9fd9SDavid Chisnall return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val); 4474bab9fd9SDavid Chisnall } 4484bab9fd9SDavid Chisnall 4494bab9fd9SDavid Chisnall string to_string(long val) 4504bab9fd9SDavid Chisnall { 4514bab9fd9SDavid Chisnall return as_string(snprintf, initial_string<string, long>()(), "%ld", val); 4524bab9fd9SDavid Chisnall } 4534bab9fd9SDavid Chisnall 4544bab9fd9SDavid Chisnall string to_string(unsigned long val) 4554bab9fd9SDavid Chisnall { 4564bab9fd9SDavid Chisnall return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val); 4574bab9fd9SDavid Chisnall } 4584bab9fd9SDavid Chisnall 4594bab9fd9SDavid Chisnall string to_string(long long val) 4604bab9fd9SDavid Chisnall { 4614bab9fd9SDavid Chisnall return as_string(snprintf, initial_string<string, long long>()(), "%lld", val); 4624bab9fd9SDavid Chisnall } 4634bab9fd9SDavid Chisnall 4644bab9fd9SDavid Chisnall string to_string(unsigned long long val) 4654bab9fd9SDavid Chisnall { 4664bab9fd9SDavid Chisnall return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val); 4674bab9fd9SDavid Chisnall } 4684bab9fd9SDavid Chisnall 4694bab9fd9SDavid Chisnall string to_string(float val) 4704bab9fd9SDavid Chisnall { 4714bab9fd9SDavid Chisnall return as_string(snprintf, initial_string<string, float>()(), "%f", val); 4724bab9fd9SDavid Chisnall } 4734bab9fd9SDavid Chisnall 4744bab9fd9SDavid Chisnall string to_string(double val) 4754bab9fd9SDavid Chisnall { 4764bab9fd9SDavid Chisnall return as_string(snprintf, initial_string<string, double>()(), "%f", val); 4774bab9fd9SDavid Chisnall } 4784bab9fd9SDavid Chisnall 4794bab9fd9SDavid Chisnall string to_string(long double val) 4804bab9fd9SDavid Chisnall { 4814bab9fd9SDavid Chisnall return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val); 4824bab9fd9SDavid Chisnall } 4834bab9fd9SDavid Chisnall 4844bab9fd9SDavid Chisnall wstring to_wstring(int val) 4854bab9fd9SDavid Chisnall { 4864bab9fd9SDavid Chisnall return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val); 4874bab9fd9SDavid Chisnall } 4884bab9fd9SDavid Chisnall 4894bab9fd9SDavid Chisnall wstring to_wstring(unsigned val) 4904bab9fd9SDavid Chisnall { 4914bab9fd9SDavid Chisnall return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val); 4924bab9fd9SDavid Chisnall } 4934bab9fd9SDavid Chisnall 4944bab9fd9SDavid Chisnall wstring to_wstring(long val) 4954bab9fd9SDavid Chisnall { 4964bab9fd9SDavid Chisnall return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val); 4974bab9fd9SDavid Chisnall } 4984bab9fd9SDavid Chisnall 4994bab9fd9SDavid Chisnall wstring to_wstring(unsigned long val) 5004bab9fd9SDavid Chisnall { 5014bab9fd9SDavid Chisnall return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val); 5024bab9fd9SDavid Chisnall } 5034bab9fd9SDavid Chisnall 5044bab9fd9SDavid Chisnall wstring to_wstring(long long val) 5054bab9fd9SDavid Chisnall { 5064bab9fd9SDavid Chisnall return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val); 5074bab9fd9SDavid Chisnall } 5084bab9fd9SDavid Chisnall 5094bab9fd9SDavid Chisnall wstring to_wstring(unsigned long long val) 5104bab9fd9SDavid Chisnall { 5114bab9fd9SDavid Chisnall return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val); 5124bab9fd9SDavid Chisnall } 5137a984708SDavid Chisnall 5147a984708SDavid Chisnall wstring to_wstring(float val) 5157a984708SDavid Chisnall { 5164bab9fd9SDavid Chisnall return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val); 5177a984708SDavid Chisnall } 5187a984708SDavid Chisnall 5197a984708SDavid Chisnall wstring to_wstring(double val) 5207a984708SDavid Chisnall { 5214bab9fd9SDavid Chisnall return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val); 5227a984708SDavid Chisnall } 5237a984708SDavid Chisnall 5247a984708SDavid Chisnall wstring to_wstring(long double val) 5257a984708SDavid Chisnall { 5264bab9fd9SDavid Chisnall return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val); 5277a984708SDavid Chisnall } 5287a984708SDavid Chisnall _LIBCPP_END_NAMESPACE_STD 529