1227825Stheraven//===------------------------- string.cpp ---------------------------------===// 2227825Stheraven// 3227825Stheraven// The LLVM Compiler Infrastructure 4227825Stheraven// 5227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 6227825Stheraven// Source Licenses. See LICENSE.TXT for details. 7227825Stheraven// 8227825Stheraven//===----------------------------------------------------------------------===// 9227825Stheraven 10227825Stheraven#include "string" 11227825Stheraven#include "cstdlib" 12227825Stheraven#include "cwchar" 13227825Stheraven#include "cerrno" 14253159Stheraven#include "limits" 15253159Stheraven#include "stdexcept" 16249998Sdim#ifdef _WIN32 17227825Stheraven#include "support/win32/support.h" 18227825Stheraven#endif // _WIN32 19227825Stheraven 20227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 21227825Stheraven 22227825Stheraventemplate class __basic_string_common<true>; 23227825Stheraven 24227825Stheraventemplate class basic_string<char>; 25227825Stheraventemplate class basic_string<wchar_t>; 26227825Stheraven 27227825Stheraventemplate 28227825Stheraven string 29227825Stheraven operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); 30227825Stheraven 31253159Stheravennamespace 32227825Stheraven{ 33253159Stheraven 34253159Stheraventemplate<typename T> 35253159Stheraveninline 36253159Stheravenvoid throw_helper( const string& msg ) 37253159Stheraven{ 38253159Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS 39253159Stheraven throw T( msg ); 40253159Stheraven#else 41253159Stheraven abort(); 42253159Stheraven#endif 43253159Stheraven} 44253159Stheraven 45253159Stheraveninline 46253159Stheravenvoid throw_from_string_out_of_range( const string& func ) 47253159Stheraven{ 48253159Stheraven throw_helper<out_of_range>(func + ": out of range"); 49253159Stheraven} 50253159Stheraven 51253159Stheraveninline 52253159Stheravenvoid throw_from_string_invalid_arg( const string& func ) 53253159Stheraven{ 54253159Stheraven throw_helper<invalid_argument>(func + ": no conversion"); 55253159Stheraven} 56253159Stheraven 57253159Stheraven// as_integer 58253159Stheraven 59253159Stheraventemplate<typename V, typename S, typename F> 60253159Stheraveninline 61253159StheravenV 62253159Stheravenas_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) 63253159Stheraven{ 64253159Stheraven typename S::value_type* ptr; 65253159Stheraven const typename S::value_type* const p = str.c_str(); 66246487Stheraven typename remove_reference<decltype(errno)>::type errno_save = errno; 67246487Stheraven errno = 0; 68253159Stheraven V r = f(p, &ptr, base); 69246487Stheraven swap(errno, errno_save); 70253159Stheraven if (errno_save == ERANGE) 71253159Stheraven throw_from_string_out_of_range(func); 72246487Stheraven if (ptr == p) 73253159Stheraven throw_from_string_invalid_arg(func); 74227825Stheraven if (idx) 75227825Stheraven *idx = static_cast<size_t>(ptr - p); 76253159Stheraven return r; 77253159Stheraven} 78253159Stheraven 79253159Stheraventemplate<typename V, typename S> 80253159Stheraveninline 81253159StheravenV 82253159Stheravenas_integer(const string& func, const S& s, size_t* idx, int base); 83253159Stheraven 84253159Stheraven// string 85253159Stheraventemplate<> 86253159Stheraveninline 87253159Stheravenint 88253159Stheravenas_integer(const string& func, const string& s, size_t* idx, int base ) 89253159Stheraven{ 90253159Stheraven // Use long as no Stantard string to integer exists. 91253159Stheraven long r = as_integer_helper<long>( func, s, idx, base, strtol ); 92253159Stheraven if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 93253159Stheraven throw_from_string_out_of_range(func); 94227825Stheraven return static_cast<int>(r); 95227825Stheraven} 96227825Stheraven 97253159Stheraventemplate<> 98253159Stheraveninline 99253159Stheravenlong 100253159Stheravenas_integer(const string& func, const string& s, size_t* idx, int base ) 101253159Stheraven{ 102253159Stheraven return as_integer_helper<long>( func, s, idx, base, strtol ); 103253159Stheraven} 104253159Stheraven 105253159Stheraventemplate<> 106253159Stheraveninline 107253159Stheravenunsigned long 108253159Stheravenas_integer( const string& func, const string& s, size_t* idx, int base ) 109253159Stheraven{ 110253159Stheraven return as_integer_helper<unsigned long>( func, s, idx, base, strtoul ); 111253159Stheraven} 112253159Stheraven 113253159Stheraventemplate<> 114253159Stheraveninline 115253159Stheravenlong long 116253159Stheravenas_integer( const string& func, const string& s, size_t* idx, int base ) 117253159Stheraven{ 118253159Stheraven return as_integer_helper<long long>( func, s, idx, base, strtoll ); 119253159Stheraven} 120253159Stheraven 121253159Stheraventemplate<> 122253159Stheraveninline 123253159Stheravenunsigned long long 124253159Stheravenas_integer( const string& func, const string& s, size_t* idx, int base ) 125253159Stheraven{ 126253159Stheraven return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull ); 127253159Stheraven} 128253159Stheraven 129253159Stheraven// wstring 130253159Stheraventemplate<> 131253159Stheraveninline 132227825Stheravenint 133253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base ) 134227825Stheraven{ 135253159Stheraven // Use long as no Stantard string to integer exists. 136253159Stheraven long r = as_integer_helper<long>( func, s, idx, base, wcstol ); 137253159Stheraven if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 138253159Stheraven throw_from_string_out_of_range(func); 139227825Stheraven return static_cast<int>(r); 140227825Stheraven} 141227825Stheraven 142253159Stheraventemplate<> 143253159Stheraveninline 144227825Stheravenlong 145253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base ) 146227825Stheraven{ 147253159Stheraven return as_integer_helper<long>( func, s, idx, base, wcstol ); 148253159Stheraven} 149253159Stheraven 150253159Stheraventemplate<> 151253159Stheraveninline 152253159Stheravenunsigned long 153253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base ) 154253159Stheraven{ 155253159Stheraven return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul ); 156253159Stheraven} 157253159Stheraven 158253159Stheraventemplate<> 159253159Stheraveninline 160253159Stheravenlong long 161253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base ) 162253159Stheraven{ 163253159Stheraven return as_integer_helper<long long>( func, s, idx, base, wcstoll ); 164253159Stheraven} 165253159Stheraven 166253159Stheraventemplate<> 167253159Stheraveninline 168253159Stheravenunsigned long long 169253159Stheravenas_integer( const string& func, const wstring& s, size_t* idx, int base ) 170253159Stheraven{ 171253159Stheraven return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull ); 172253159Stheraven} 173253159Stheraven 174253159Stheraven// as_float 175253159Stheraven 176253159Stheraventemplate<typename V, typename S, typename F> 177253159Stheraveninline 178253159StheravenV 179253159Stheravenas_float_helper(const string& func, const S& str, size_t* idx, F f ) 180253159Stheraven{ 181253159Stheraven typename S::value_type* ptr; 182253159Stheraven const typename S::value_type* const p = str.c_str(); 183246487Stheraven typename remove_reference<decltype(errno)>::type errno_save = errno; 184246487Stheraven errno = 0; 185253159Stheraven V r = f(p, &ptr); 186246487Stheraven swap(errno, errno_save); 187246487Stheraven if (errno_save == ERANGE) 188253159Stheraven throw_from_string_out_of_range(func); 189246487Stheraven if (ptr == p) 190253159Stheraven throw_from_string_invalid_arg(func); 191227825Stheraven if (idx) 192227825Stheraven *idx = static_cast<size_t>(ptr - p); 193227825Stheraven return r; 194227825Stheraven} 195227825Stheraven 196253159Stheraventemplate<typename V, typename S> 197253159Stheraveninline 198253159StheravenV as_float( const string& func, const S& s, size_t* idx = nullptr ); 199253159Stheraven 200253159Stheraventemplate<> 201253159Stheraveninline 202253159Stheravenfloat 203253159Stheravenas_float( const string& func, const string& s, size_t* idx ) 204253159Stheraven{ 205253159Stheraven return as_float_helper<float>( func, s, idx, strtof ); 206253159Stheraven} 207253159Stheraven 208253159Stheraventemplate<> 209253159Stheraveninline 210253159Stheravendouble 211253159Stheravenas_float(const string& func, const string& s, size_t* idx ) 212253159Stheraven{ 213253159Stheraven return as_float_helper<double>( func, s, idx, strtod ); 214253159Stheraven} 215253159Stheraven 216253159Stheraventemplate<> 217253159Stheraveninline 218253159Stheravenlong double 219253159Stheravenas_float( const string& func, const string& s, size_t* idx ) 220253159Stheraven{ 221253159Stheraven return as_float_helper<long double>( func, s, idx, strtold ); 222253159Stheraven} 223253159Stheraven 224253159Stheraventemplate<> 225253159Stheraveninline 226253159Stheravenfloat 227253159Stheravenas_float( const string& func, const wstring& s, size_t* idx ) 228253159Stheraven{ 229253159Stheraven return as_float_helper<float>( func, s, idx, wcstof ); 230253159Stheraven} 231253159Stheraven 232253159Stheraventemplate<> 233253159Stheraveninline 234253159Stheravendouble 235253159Stheravenas_float( const string& func, const wstring& s, size_t* idx ) 236253159Stheraven{ 237253159Stheraven return as_float_helper<double>( func, s, idx, wcstod ); 238253159Stheraven} 239253159Stheraven 240253159Stheraventemplate<> 241253159Stheraveninline 242253159Stheravenlong double 243253159Stheravenas_float( const string& func, const wstring& s, size_t* idx ) 244253159Stheraven{ 245253159Stheraven return as_float_helper<long double>( func, s, idx, wcstold ); 246253159Stheraven} 247253159Stheraven 248253159Stheraven} // unnamed namespace 249253159Stheraven 250253159Stheravenint 251253159Stheravenstoi(const string& str, size_t* idx, int base) 252253159Stheraven{ 253253159Stheraven return as_integer<int>( "stoi", str, idx, base ); 254253159Stheraven} 255253159Stheraven 256253159Stheravenint 257253159Stheravenstoi(const wstring& str, size_t* idx, int base) 258253159Stheraven{ 259253159Stheraven return as_integer<int>( "stoi", str, idx, base ); 260253159Stheraven} 261253159Stheraven 262227825Stheravenlong 263253159Stheravenstol(const string& str, size_t* idx, int base) 264253159Stheraven{ 265253159Stheraven return as_integer<long>( "stol", str, idx, base ); 266253159Stheraven} 267253159Stheraven 268253159Stheravenlong 269227825Stheravenstol(const wstring& str, size_t* idx, int base) 270227825Stheraven{ 271253159Stheraven return as_integer<long>( "stol", str, idx, base ); 272227825Stheraven} 273227825Stheraven 274227825Stheravenunsigned long 275227825Stheravenstoul(const string& str, size_t* idx, int base) 276227825Stheraven{ 277253159Stheraven return as_integer<unsigned long>( "stoul", str, idx, base ); 278227825Stheraven} 279227825Stheraven 280227825Stheravenunsigned long 281227825Stheravenstoul(const wstring& str, size_t* idx, int base) 282227825Stheraven{ 283253159Stheraven return as_integer<unsigned long>( "stoul", str, idx, base ); 284227825Stheraven} 285227825Stheraven 286227825Stheravenlong long 287227825Stheravenstoll(const string& str, size_t* idx, int base) 288227825Stheraven{ 289253159Stheraven return as_integer<long long>( "stoll", str, idx, base ); 290227825Stheraven} 291227825Stheraven 292227825Stheravenlong long 293227825Stheravenstoll(const wstring& str, size_t* idx, int base) 294227825Stheraven{ 295253159Stheraven return as_integer<long long>( "stoll", str, idx, base ); 296227825Stheraven} 297227825Stheraven 298227825Stheravenunsigned long long 299227825Stheravenstoull(const string& str, size_t* idx, int base) 300227825Stheraven{ 301253159Stheraven return as_integer<unsigned long long>( "stoull", str, idx, base ); 302227825Stheraven} 303227825Stheraven 304227825Stheravenunsigned long long 305227825Stheravenstoull(const wstring& str, size_t* idx, int base) 306227825Stheraven{ 307253159Stheraven return as_integer<unsigned long long>( "stoull", str, idx, base ); 308227825Stheraven} 309227825Stheraven 310227825Stheravenfloat 311227825Stheravenstof(const string& str, size_t* idx) 312227825Stheraven{ 313253159Stheraven return as_float<float>( "stof", str, idx ); 314227825Stheraven} 315227825Stheraven 316227825Stheravenfloat 317227825Stheravenstof(const wstring& str, size_t* idx) 318227825Stheraven{ 319253159Stheraven return as_float<float>( "stof", str, idx ); 320227825Stheraven} 321227825Stheraven 322227825Stheravendouble 323227825Stheravenstod(const string& str, size_t* idx) 324227825Stheraven{ 325253159Stheraven return as_float<double>( "stod", str, idx ); 326227825Stheraven} 327227825Stheraven 328227825Stheravendouble 329227825Stheravenstod(const wstring& str, size_t* idx) 330227825Stheraven{ 331253159Stheraven return as_float<double>( "stod", str, idx ); 332227825Stheraven} 333227825Stheraven 334227825Stheravenlong double 335227825Stheravenstold(const string& str, size_t* idx) 336227825Stheraven{ 337253159Stheraven return as_float<long double>( "stold", str, idx ); 338227825Stheraven} 339227825Stheraven 340227825Stheravenlong double 341227825Stheravenstold(const wstring& str, size_t* idx) 342227825Stheraven{ 343253159Stheraven return as_float<long double>( "stold", str, idx ); 344227825Stheraven} 345227825Stheraven 346253159Stheraven// to_string 347253159Stheraven 348253159Stheravennamespace 349227825Stheraven{ 350253159Stheraven 351253159Stheraven// as_string 352253159Stheraven 353253159Stheraventemplate<typename S, typename P, typename V > 354253159Stheraveninline 355253159StheravenS 356253159Stheravenas_string(P sprintf_like, S s, const typename S::value_type* fmt, V a) 357253159Stheraven{ 358253159Stheraven typedef typename S::size_type size_type; 359253159Stheraven size_type available = s.size(); 360227825Stheraven while (true) 361227825Stheraven { 362253159Stheraven int status = sprintf_like(&s[0], available + 1, fmt, a); 363253159Stheraven if ( status >= 0 ) 364227825Stheraven { 365253159Stheraven size_type used = static_cast<size_type>(status); 366253159Stheraven if ( used <= available ) 367253159Stheraven { 368253159Stheraven s.resize( used ); 369253159Stheraven break; 370253159Stheraven } 371253159Stheraven available = used; // Assume this is advice of how much space we need. 372227825Stheraven } 373253159Stheraven else 374253159Stheraven available = available * 2 + 1; 375253159Stheraven s.resize(available); 376227825Stheraven } 377227825Stheraven return s; 378227825Stheraven} 379227825Stheraven 380253159Stheraventemplate <class S, class V, bool = is_floating_point<V>::value> 381253159Stheravenstruct initial_string; 382253159Stheraven 383253159Stheraventemplate <class V, bool b> 384253159Stheravenstruct initial_string<string, V, b> 385227825Stheraven{ 386253159Stheraven string 387253159Stheraven operator()() const 388227825Stheraven { 389253159Stheraven string s; 390253159Stheraven s.resize(s.capacity()); 391253159Stheraven return s; 392227825Stheraven } 393253159Stheraven}; 394227825Stheraven 395253159Stheraventemplate <class V> 396253159Stheravenstruct initial_string<wstring, V, false> 397227825Stheraven{ 398253159Stheraven wstring 399253159Stheraven operator()() const 400227825Stheraven { 401253159Stheraven const size_t n = (numeric_limits<unsigned long long>::digits / 3) 402253159Stheraven + ((numeric_limits<unsigned long long>::digits % 3) != 0) 403253159Stheraven + 1; 404253159Stheraven wstring s(n, wchar_t()); 405253159Stheraven s.resize(s.capacity()); 406253159Stheraven return s; 407227825Stheraven } 408253159Stheraven}; 409227825Stheraven 410253159Stheraventemplate <class V> 411253159Stheravenstruct initial_string<wstring, V, true> 412227825Stheraven{ 413253159Stheraven wstring 414253159Stheraven operator()() const 415227825Stheraven { 416253159Stheraven wstring s(20, wchar_t()); 417253159Stheraven s.resize(s.capacity()); 418253159Stheraven return s; 419227825Stheraven } 420253159Stheraven}; 421253159Stheraven 422253159Stheraventypedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); 423253159Stheraven 424253159Stheraveninline 425253159Stheravenwide_printf 426253159Stheravenget_swprintf() 427253159Stheraven{ 428253159Stheraven#ifndef _WIN32 429253159Stheraven return swprintf; 430253159Stheraven#else 431253159Stheraven return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf); 432253159Stheraven#endif 433227825Stheraven} 434227825Stheraven 435253159Stheraven} // unnamed namespace 436253159Stheraven 437253159Stheravenstring to_string(int val) 438253159Stheraven{ 439253159Stheraven return as_string(snprintf, initial_string<string, int>()(), "%d", val); 440253159Stheraven} 441253159Stheraven 442253159Stheravenstring to_string(unsigned val) 443253159Stheraven{ 444253159Stheraven return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val); 445253159Stheraven} 446253159Stheraven 447253159Stheravenstring to_string(long val) 448253159Stheraven{ 449253159Stheraven return as_string(snprintf, initial_string<string, long>()(), "%ld", val); 450253159Stheraven} 451253159Stheraven 452253159Stheravenstring to_string(unsigned long val) 453253159Stheraven{ 454253159Stheraven return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val); 455253159Stheraven} 456253159Stheraven 457227825Stheravenstring to_string(long long val) 458227825Stheraven{ 459253159Stheraven return as_string(snprintf, initial_string<string, long long>()(), "%lld", val); 460227825Stheraven} 461227825Stheraven 462227825Stheravenstring to_string(unsigned long long val) 463227825Stheraven{ 464253159Stheraven return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val); 465227825Stheraven} 466227825Stheraven 467227825Stheravenstring to_string(float val) 468227825Stheraven{ 469253159Stheraven return as_string(snprintf, initial_string<string, float>()(), "%f", val); 470227825Stheraven} 471227825Stheraven 472227825Stheravenstring to_string(double val) 473227825Stheraven{ 474253159Stheraven return as_string(snprintf, initial_string<string, double>()(), "%f", val); 475227825Stheraven} 476227825Stheraven 477227825Stheravenstring to_string(long double val) 478227825Stheraven{ 479253159Stheraven return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val); 480227825Stheraven} 481227825Stheraven 482227825Stheravenwstring to_wstring(int val) 483227825Stheraven{ 484253159Stheraven return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val); 485227825Stheraven} 486227825Stheraven 487227825Stheravenwstring to_wstring(unsigned val) 488227825Stheraven{ 489253159Stheraven return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val); 490227825Stheraven} 491227825Stheraven 492227825Stheravenwstring to_wstring(long val) 493227825Stheraven{ 494253159Stheraven return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val); 495227825Stheraven} 496227825Stheraven 497227825Stheravenwstring to_wstring(unsigned long val) 498227825Stheraven{ 499253159Stheraven return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val); 500227825Stheraven} 501227825Stheraven 502227825Stheravenwstring to_wstring(long long val) 503227825Stheraven{ 504253159Stheraven return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val); 505227825Stheraven} 506227825Stheraven 507227825Stheravenwstring to_wstring(unsigned long long val) 508227825Stheraven{ 509253159Stheraven return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val); 510227825Stheraven} 511227825Stheraven 512227825Stheravenwstring to_wstring(float val) 513227825Stheraven{ 514253159Stheraven return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val); 515227825Stheraven} 516227825Stheraven 517227825Stheravenwstring to_wstring(double val) 518227825Stheraven{ 519253159Stheraven return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val); 520227825Stheraven} 521227825Stheraven 522227825Stheravenwstring to_wstring(long double val) 523227825Stheraven{ 524253159Stheraven return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val); 525227825Stheraven} 526227825Stheraven_LIBCPP_END_NAMESPACE_STD 527