11573Srgrimes//===------------------------- string.cpp ---------------------------------===// 21573Srgrimes// 31573Srgrimes// The LLVM Compiler Infrastructure 41573Srgrimes// 51573Srgrimes// This file is dual licensed under the MIT and the University of Illinois Open 61573Srgrimes// Source Licenses. See LICENSE.TXT for details. 71573Srgrimes// 81573Srgrimes//===----------------------------------------------------------------------===// 91573Srgrimes 101573Srgrimes#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; 111573Srgrimes 121573Srgrimes#include "string" 131573Srgrimes#include "cstdlib" 141573Srgrimes#include "cwchar" 151573Srgrimes#include "cerrno" 161573Srgrimes#include "limits" 171573Srgrimes#include "stdexcept" 181573Srgrimes#ifdef _LIBCPP_MSVCRT 191573Srgrimes#include "support/win32/support.h" 201573Srgrimes#endif // _LIBCPP_MSVCRT 211573Srgrimes#include <stdio.h> 221573Srgrimes 231573Srgrimes_LIBCPP_BEGIN_NAMESPACE_STD 241573Srgrimes 251573Srgrimestemplate class __basic_string_common<true>; 261573Srgrimes 271573Srgrimestemplate class basic_string<char>; 281573Srgrimestemplate class basic_string<wchar_t>; 291573Srgrimes 301573Srgrimestemplate 313565Swollman string 321573Srgrimes operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); 3390039Sobrien 3490039Sobriennamespace 351573Srgrimes{ 361573Srgrimes 371573Srgrimestemplate<typename T> 381573Srgrimesinline 393565Swollmanvoid throw_helper( const string& msg ) 40153009Sambrisko{ 41153009Sambrisko#ifndef _LIBCPP_NO_EXCEPTIONS 421573Srgrimes throw T( msg ); 431573Srgrimes#else 4474729Speter printf("%s\n", msg.c_str()); 451573Srgrimes abort(); 461573Srgrimes#endif 471573Srgrimes} 48184177Skib 493565Swollmaninline 501573Srgrimesvoid throw_from_string_out_of_range( const string& func ) 511573Srgrimes{ 52184177Skib throw_helper<out_of_range>(func + ": out of range"); 531573Srgrimes} 541573Srgrimes 55184177Skibinline 56184177Skibvoid throw_from_string_invalid_arg( const string& func ) 57184177Skib{ 58184177Skib throw_helper<invalid_argument>(func + ": no conversion"); 59184177Skib} 60184177Skib 61184177Skib// as_integer 62184177Skib 63184177Skibtemplate<typename V, typename S, typename F> 64184177Skibinline 65184177SkibV 66184177Skibas_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) 67184177Skib{ 68184177Skib typename S::value_type* ptr; 693565Swollman const typename S::value_type* const p = str.c_str(); 70184177Skib typename remove_reference<decltype(errno)>::type errno_save = errno; 711573Srgrimes errno = 0; 721573Srgrimes V r = f(p, &ptr, base); 73184177Skib swap(errno, errno_save); 743565Swollman if (errno_save == ERANGE) 75184177Skib throw_from_string_out_of_range(func); 76184177Skib if (ptr == p) 773565Swollman throw_from_string_invalid_arg(func); 783565Swollman if (idx) 793565Swollman *idx = static_cast<size_t>(ptr - p); 803565Swollman return r; 81184177Skib} 82184177Skib 831573Srgrimestemplate<typename V, typename S> 84153002Sambriskoinline 85184177SkibV 86184177Skibas_integer(const string& func, const S& s, size_t* idx, int base); 87184177Skib 88184177Skib// string 89184177Skibtemplate<> 90184177Skibinline 91184177Skibint 92184177Skibas_integer(const string& func, const string& s, size_t* idx, int base ) 939817Smpp{ 94184177Skib // Use long as no Standard string to integer exists. 953565Swollman long r = as_integer_helper<long>( func, s, idx, base, strtol ); 96184177Skib if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 973565Swollman throw_from_string_out_of_range(func); 98184177Skib return static_cast<int>(r); 99184177Skib} 100153002Sambrisko 101184177Skibtemplate<> 102184177Skibinline 1031573Srgrimeslong 104184177Skibas_integer(const string& func, const string& s, size_t* idx, int base ) 105184177Skib{ 106184177Skib return as_integer_helper<long>( func, s, idx, base, strtol ); 107184177Skib} 108184177Skib 109184177Skibtemplate<> 110184177Skibinline 111184177Skibunsigned long 112184177Skibas_integer( const string& func, const string& s, size_t* idx, int base ) 113184177Skib{ 114184177Skib return as_integer_helper<unsigned long>( func, s, idx, base, strtoul ); 115184177Skib} 116184177Skib 117184177Skibtemplate<> 118184177Skibinline 119184177Skiblong long 120184177Skibas_integer( const string& func, const string& s, size_t* idx, int base ) 121184177Skib{ 122184177Skib return as_integer_helper<long long>( func, s, idx, base, strtoll ); 123184177Skib} 124184177Skib 125184177Skibtemplate<> 1263565Swollmaninline 127184177Skibunsigned long long 128184177Skibas_integer( const string& func, const string& s, size_t* idx, int base ) 129153002Sambrisko{ 130184177Skib return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull ); 131184177Skib} 132184177Skib 133184177Skib// wstring 134184177Skibtemplate<> 135184177Skibinline 136184185Skibint 137184177Skibas_integer( const string& func, const wstring& s, size_t* idx, int base ) 138184177Skib{ 139184177Skib // Use long as no Stantard string to integer exists. 140184177Skib long r = as_integer_helper<long>( func, s, idx, base, wcstol ); 141184177Skib if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 142184177Skib throw_from_string_out_of_range(func); 143184177Skib return static_cast<int>(r); 144184177Skib} 1451573Srgrimes 1461573Srgrimestemplate<> 147inline 148long 149as_integer( const string& func, const wstring& s, size_t* idx, int base ) 150{ 151 return as_integer_helper<long>( func, s, idx, base, wcstol ); 152} 153 154template<> 155inline 156unsigned long 157as_integer( const string& func, const wstring& s, size_t* idx, int base ) 158{ 159 return as_integer_helper<unsigned long>( func, s, idx, base, wcstoul ); 160} 161 162template<> 163inline 164long long 165as_integer( const string& func, const wstring& s, size_t* idx, int base ) 166{ 167 return as_integer_helper<long long>( func, s, idx, base, wcstoll ); 168} 169 170template<> 171inline 172unsigned long long 173as_integer( const string& func, const wstring& s, size_t* idx, int base ) 174{ 175 return as_integer_helper<unsigned long long>( func, s, idx, base, wcstoull ); 176} 177 178// as_float 179 180template<typename V, typename S, typename F> 181inline 182V 183as_float_helper(const string& func, const S& str, size_t* idx, F f ) 184{ 185 typename S::value_type* ptr; 186 const typename S::value_type* const p = str.c_str(); 187 typename remove_reference<decltype(errno)>::type errno_save = errno; 188 errno = 0; 189 V r = f(p, &ptr); 190 swap(errno, errno_save); 191 if (errno_save == ERANGE) 192 throw_from_string_out_of_range(func); 193 if (ptr == p) 194 throw_from_string_invalid_arg(func); 195 if (idx) 196 *idx = static_cast<size_t>(ptr - p); 197 return r; 198} 199 200template<typename V, typename S> 201inline 202V as_float( const string& func, const S& s, size_t* idx = nullptr ); 203 204template<> 205inline 206float 207as_float( const string& func, const string& s, size_t* idx ) 208{ 209 return as_float_helper<float>( func, s, idx, strtof ); 210} 211 212template<> 213inline 214double 215as_float(const string& func, const string& s, size_t* idx ) 216{ 217 return as_float_helper<double>( func, s, idx, strtod ); 218} 219 220template<> 221inline 222long double 223as_float( const string& func, const string& s, size_t* idx ) 224{ 225 return as_float_helper<long double>( func, s, idx, strtold ); 226} 227 228template<> 229inline 230float 231as_float( const string& func, const wstring& s, size_t* idx ) 232{ 233 return as_float_helper<float>( func, s, idx, wcstof ); 234} 235 236template<> 237inline 238double 239as_float( const string& func, const wstring& s, size_t* idx ) 240{ 241 return as_float_helper<double>( func, s, idx, wcstod ); 242} 243 244template<> 245inline 246long double 247as_float( const string& func, const wstring& s, size_t* idx ) 248{ 249 return as_float_helper<long double>( func, s, idx, wcstold ); 250} 251 252} // unnamed namespace 253 254int 255stoi(const string& str, size_t* idx, int base) 256{ 257 return as_integer<int>( "stoi", str, idx, base ); 258} 259 260int 261stoi(const wstring& str, size_t* idx, int base) 262{ 263 return as_integer<int>( "stoi", str, idx, base ); 264} 265 266long 267stol(const string& str, size_t* idx, int base) 268{ 269 return as_integer<long>( "stol", str, idx, base ); 270} 271 272long 273stol(const wstring& str, size_t* idx, int base) 274{ 275 return as_integer<long>( "stol", str, idx, base ); 276} 277 278unsigned long 279stoul(const string& str, size_t* idx, int base) 280{ 281 return as_integer<unsigned long>( "stoul", str, idx, base ); 282} 283 284unsigned long 285stoul(const wstring& str, size_t* idx, int base) 286{ 287 return as_integer<unsigned long>( "stoul", str, idx, base ); 288} 289 290long long 291stoll(const string& str, size_t* idx, int base) 292{ 293 return as_integer<long long>( "stoll", str, idx, base ); 294} 295 296long long 297stoll(const wstring& str, size_t* idx, int base) 298{ 299 return as_integer<long long>( "stoll", str, idx, base ); 300} 301 302unsigned long long 303stoull(const string& str, size_t* idx, int base) 304{ 305 return as_integer<unsigned long long>( "stoull", str, idx, base ); 306} 307 308unsigned long long 309stoull(const wstring& str, size_t* idx, int base) 310{ 311 return as_integer<unsigned long long>( "stoull", str, idx, base ); 312} 313 314float 315stof(const string& str, size_t* idx) 316{ 317 return as_float<float>( "stof", str, idx ); 318} 319 320float 321stof(const wstring& str, size_t* idx) 322{ 323 return as_float<float>( "stof", str, idx ); 324} 325 326double 327stod(const string& str, size_t* idx) 328{ 329 return as_float<double>( "stod", str, idx ); 330} 331 332double 333stod(const wstring& str, size_t* idx) 334{ 335 return as_float<double>( "stod", str, idx ); 336} 337 338long double 339stold(const string& str, size_t* idx) 340{ 341 return as_float<long double>( "stold", str, idx ); 342} 343 344long double 345stold(const wstring& str, size_t* idx) 346{ 347 return as_float<long double>( "stold", str, idx ); 348} 349 350// to_string 351 352namespace 353{ 354 355// as_string 356 357template<typename S, typename P, typename V > 358inline 359S 360as_string(P sprintf_like, S s, const typename S::value_type* fmt, V a) 361{ 362 typedef typename S::size_type size_type; 363 size_type available = s.size(); 364 while (true) 365 { 366 int status = sprintf_like(&s[0], available + 1, fmt, a); 367 if ( status >= 0 ) 368 { 369 size_type used = static_cast<size_type>(status); 370 if ( used <= available ) 371 { 372 s.resize( used ); 373 break; 374 } 375 available = used; // Assume this is advice of how much space we need. 376 } 377 else 378 available = available * 2 + 1; 379 s.resize(available); 380 } 381 return s; 382} 383 384template <class S, class V, bool = is_floating_point<V>::value> 385struct initial_string; 386 387template <class V, bool b> 388struct initial_string<string, V, b> 389{ 390 string 391 operator()() const 392 { 393 string s; 394 s.resize(s.capacity()); 395 return s; 396 } 397}; 398 399template <class V> 400struct initial_string<wstring, V, false> 401{ 402 wstring 403 operator()() const 404 { 405 const size_t n = (numeric_limits<unsigned long long>::digits / 3) 406 + ((numeric_limits<unsigned long long>::digits % 3) != 0) 407 + 1; 408 wstring s(n, wchar_t()); 409 s.resize(s.capacity()); 410 return s; 411 } 412}; 413 414template <class V> 415struct initial_string<wstring, V, true> 416{ 417 wstring 418 operator()() const 419 { 420 wstring s(20, wchar_t()); 421 s.resize(s.capacity()); 422 return s; 423 } 424}; 425 426typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); 427 428inline 429wide_printf 430get_swprintf() 431{ 432#ifndef _LIBCPP_MSVCRT 433 return swprintf; 434#else 435 return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf); 436#endif 437} 438 439} // unnamed namespace 440 441string to_string(int val) 442{ 443 return as_string(snprintf, initial_string<string, int>()(), "%d", val); 444} 445 446string to_string(unsigned val) 447{ 448 return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val); 449} 450 451string to_string(long val) 452{ 453 return as_string(snprintf, initial_string<string, long>()(), "%ld", val); 454} 455 456string to_string(unsigned long val) 457{ 458 return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val); 459} 460 461string to_string(long long val) 462{ 463 return as_string(snprintf, initial_string<string, long long>()(), "%lld", val); 464} 465 466string to_string(unsigned long long val) 467{ 468 return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val); 469} 470 471string to_string(float val) 472{ 473 return as_string(snprintf, initial_string<string, float>()(), "%f", val); 474} 475 476string to_string(double val) 477{ 478 return as_string(snprintf, initial_string<string, double>()(), "%f", val); 479} 480 481string to_string(long double val) 482{ 483 return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val); 484} 485 486wstring to_wstring(int val) 487{ 488 return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val); 489} 490 491wstring to_wstring(unsigned val) 492{ 493 return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val); 494} 495 496wstring to_wstring(long val) 497{ 498 return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val); 499} 500 501wstring to_wstring(unsigned long val) 502{ 503 return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val); 504} 505 506wstring to_wstring(long long val) 507{ 508 return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val); 509} 510 511wstring to_wstring(unsigned long long val) 512{ 513 return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val); 514} 515 516wstring to_wstring(float val) 517{ 518 return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val); 519} 520 521wstring to_wstring(double val) 522{ 523 return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val); 524} 525 526wstring to_wstring(long double val) 527{ 528 return as_string(get_swprintf(), initial_string<wstring, long double>()(), L"%Lf", val); 529} 530_LIBCPP_END_NAMESPACE_STD 531