1 //===------------------------- string.cpp ---------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; 11 12 #include "string" 13 #include "cstdlib" 14 #include "cwchar" 15 #include "cerrno" 16 #include "limits" 17 #include "stdexcept" 18 #ifdef _LIBCPP_MSVCRT 19 #include "support/win32/support.h" 20 #endif // _LIBCPP_MSVCRT 21 #include <stdio.h> 22 23 _LIBCPP_BEGIN_NAMESPACE_STD 24 25 template class __basic_string_common<true>; 26 27 template class basic_string<char>; 28 template class basic_string<wchar_t>; 29 30 template 31 string 32 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); 33 34 namespace 35 { 36 37 template<typename T> 38 inline 39 void throw_helper( const string& msg ) 40 { 41 #ifndef _LIBCPP_NO_EXCEPTIONS 42 throw T( msg ); 43 #else 44 printf("%s\n", msg.c_str()); 45 abort(); 46 #endif 47 } 48 49 inline 50 void throw_from_string_out_of_range( const string& func ) 51 { 52 throw_helper<out_of_range>(func + ": out of range"); 53 } 54 55 inline 56 void throw_from_string_invalid_arg( const string& func ) 57 { 58 throw_helper<invalid_argument>(func + ": no conversion"); 59 } 60 61 // as_integer 62 63 template<typename V, typename S, typename F> 64 inline 65 V 66 as_integer_helper(const string& func, const S& str, size_t* idx, int base, F f) 67 { 68 typename S::value_type* ptr; 69 const typename S::value_type* const p = str.c_str(); 70 typename remove_reference<decltype(errno)>::type errno_save = errno; 71 errno = 0; 72 V r = f(p, &ptr, base); 73 swap(errno, errno_save); 74 if (errno_save == ERANGE) 75 throw_from_string_out_of_range(func); 76 if (ptr == p) 77 throw_from_string_invalid_arg(func); 78 if (idx) 79 *idx = static_cast<size_t>(ptr - p); 80 return r; 81 } 82 83 template<typename V, typename S> 84 inline 85 V 86 as_integer(const string& func, const S& s, size_t* idx, int base); 87 88 // string 89 template<> 90 inline 91 int 92 as_integer(const string& func, const string& s, size_t* idx, int base ) 93 { 94 // Use long as no Standard string to integer exists. 95 long r = as_integer_helper<long>( func, s, idx, base, strtol ); 96 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 97 throw_from_string_out_of_range(func); 98 return static_cast<int>(r); 99 } 100 101 template<> 102 inline 103 long 104 as_integer(const string& func, const string& s, size_t* idx, int base ) 105 { 106 return as_integer_helper<long>( func, s, idx, base, strtol ); 107 } 108 109 template<> 110 inline 111 unsigned long 112 as_integer( const string& func, const string& s, size_t* idx, int base ) 113 { 114 return as_integer_helper<unsigned long>( func, s, idx, base, strtoul ); 115 } 116 117 template<> 118 inline 119 long long 120 as_integer( const string& func, const string& s, size_t* idx, int base ) 121 { 122 return as_integer_helper<long long>( func, s, idx, base, strtoll ); 123 } 124 125 template<> 126 inline 127 unsigned long long 128 as_integer( const string& func, const string& s, size_t* idx, int base ) 129 { 130 return as_integer_helper<unsigned long long>( func, s, idx, base, strtoull ); 131 } 132 133 // wstring 134 template<> 135 inline 136 int 137 as_integer( const string& func, const wstring& s, size_t* idx, int base ) 138 { 139 // Use long as no Stantard string to integer exists. 140 long r = as_integer_helper<long>( func, s, idx, base, wcstol ); 141 if (r < numeric_limits<int>::min() || numeric_limits<int>::max() < r) 142 throw_from_string_out_of_range(func); 143 return static_cast<int>(r); 144 } 145 146 template<> 147 inline 148 long 149 as_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 154 template<> 155 inline 156 unsigned long 157 as_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 162 template<> 163 inline 164 long long 165 as_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 170 template<> 171 inline 172 unsigned long long 173 as_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 180 template<typename V, typename S, typename F> 181 inline 182 V 183 as_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 200 template<typename V, typename S> 201 inline 202 V as_float( const string& func, const S& s, size_t* idx = nullptr ); 203 204 template<> 205 inline 206 float 207 as_float( const string& func, const string& s, size_t* idx ) 208 { 209 return as_float_helper<float>( func, s, idx, strtof ); 210 } 211 212 template<> 213 inline 214 double 215 as_float(const string& func, const string& s, size_t* idx ) 216 { 217 return as_float_helper<double>( func, s, idx, strtod ); 218 } 219 220 template<> 221 inline 222 long double 223 as_float( const string& func, const string& s, size_t* idx ) 224 { 225 return as_float_helper<long double>( func, s, idx, strtold ); 226 } 227 228 template<> 229 inline 230 float 231 as_float( const string& func, const wstring& s, size_t* idx ) 232 { 233 return as_float_helper<float>( func, s, idx, wcstof ); 234 } 235 236 template<> 237 inline 238 double 239 as_float( const string& func, const wstring& s, size_t* idx ) 240 { 241 return as_float_helper<double>( func, s, idx, wcstod ); 242 } 243 244 template<> 245 inline 246 long double 247 as_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 254 int 255 stoi(const string& str, size_t* idx, int base) 256 { 257 return as_integer<int>( "stoi", str, idx, base ); 258 } 259 260 int 261 stoi(const wstring& str, size_t* idx, int base) 262 { 263 return as_integer<int>( "stoi", str, idx, base ); 264 } 265 266 long 267 stol(const string& str, size_t* idx, int base) 268 { 269 return as_integer<long>( "stol", str, idx, base ); 270 } 271 272 long 273 stol(const wstring& str, size_t* idx, int base) 274 { 275 return as_integer<long>( "stol", str, idx, base ); 276 } 277 278 unsigned long 279 stoul(const string& str, size_t* idx, int base) 280 { 281 return as_integer<unsigned long>( "stoul", str, idx, base ); 282 } 283 284 unsigned long 285 stoul(const wstring& str, size_t* idx, int base) 286 { 287 return as_integer<unsigned long>( "stoul", str, idx, base ); 288 } 289 290 long long 291 stoll(const string& str, size_t* idx, int base) 292 { 293 return as_integer<long long>( "stoll", str, idx, base ); 294 } 295 296 long long 297 stoll(const wstring& str, size_t* idx, int base) 298 { 299 return as_integer<long long>( "stoll", str, idx, base ); 300 } 301 302 unsigned long long 303 stoull(const string& str, size_t* idx, int base) 304 { 305 return as_integer<unsigned long long>( "stoull", str, idx, base ); 306 } 307 308 unsigned long long 309 stoull(const wstring& str, size_t* idx, int base) 310 { 311 return as_integer<unsigned long long>( "stoull", str, idx, base ); 312 } 313 314 float 315 stof(const string& str, size_t* idx) 316 { 317 return as_float<float>( "stof", str, idx ); 318 } 319 320 float 321 stof(const wstring& str, size_t* idx) 322 { 323 return as_float<float>( "stof", str, idx ); 324 } 325 326 double 327 stod(const string& str, size_t* idx) 328 { 329 return as_float<double>( "stod", str, idx ); 330 } 331 332 double 333 stod(const wstring& str, size_t* idx) 334 { 335 return as_float<double>( "stod", str, idx ); 336 } 337 338 long double 339 stold(const string& str, size_t* idx) 340 { 341 return as_float<long double>( "stold", str, idx ); 342 } 343 344 long double 345 stold(const wstring& str, size_t* idx) 346 { 347 return as_float<long double>( "stold", str, idx ); 348 } 349 350 // to_string 351 352 namespace 353 { 354 355 // as_string 356 357 template<typename S, typename P, typename V > 358 inline 359 S 360 as_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 384 template <class S, class V, bool = is_floating_point<V>::value> 385 struct initial_string; 386 387 template <class V, bool b> 388 struct 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 399 template <class V> 400 struct 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 414 template <class V> 415 struct 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 426 typedef int (*wide_printf)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...); 427 428 inline 429 wide_printf 430 get_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 441 string to_string(int val) 442 { 443 return as_string(snprintf, initial_string<string, int>()(), "%d", val); 444 } 445 446 string to_string(unsigned val) 447 { 448 return as_string(snprintf, initial_string<string, unsigned>()(), "%u", val); 449 } 450 451 string to_string(long val) 452 { 453 return as_string(snprintf, initial_string<string, long>()(), "%ld", val); 454 } 455 456 string to_string(unsigned long val) 457 { 458 return as_string(snprintf, initial_string<string, unsigned long>()(), "%lu", val); 459 } 460 461 string to_string(long long val) 462 { 463 return as_string(snprintf, initial_string<string, long long>()(), "%lld", val); 464 } 465 466 string to_string(unsigned long long val) 467 { 468 return as_string(snprintf, initial_string<string, unsigned long long>()(), "%llu", val); 469 } 470 471 string to_string(float val) 472 { 473 return as_string(snprintf, initial_string<string, float>()(), "%f", val); 474 } 475 476 string to_string(double val) 477 { 478 return as_string(snprintf, initial_string<string, double>()(), "%f", val); 479 } 480 481 string to_string(long double val) 482 { 483 return as_string(snprintf, initial_string<string, long double>()(), "%Lf", val); 484 } 485 486 wstring to_wstring(int val) 487 { 488 return as_string(get_swprintf(), initial_string<wstring, int>()(), L"%d", val); 489 } 490 491 wstring to_wstring(unsigned val) 492 { 493 return as_string(get_swprintf(), initial_string<wstring, unsigned>()(), L"%u", val); 494 } 495 496 wstring to_wstring(long val) 497 { 498 return as_string(get_swprintf(), initial_string<wstring, long>()(), L"%ld", val); 499 } 500 501 wstring to_wstring(unsigned long val) 502 { 503 return as_string(get_swprintf(), initial_string<wstring, unsigned long>()(), L"%lu", val); 504 } 505 506 wstring to_wstring(long long val) 507 { 508 return as_string(get_swprintf(), initial_string<wstring, long long>()(), L"%lld", val); 509 } 510 511 wstring to_wstring(unsigned long long val) 512 { 513 return as_string(get_swprintf(), initial_string<wstring, unsigned long long>()(), L"%llu", val); 514 } 515 516 wstring to_wstring(float val) 517 { 518 return as_string(get_swprintf(), initial_string<wstring, float>()(), L"%f", val); 519 } 520 521 wstring to_wstring(double val) 522 { 523 return as_string(get_swprintf(), initial_string<wstring, double>()(), L"%f", val); 524 } 525 526 wstring 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