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