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 #include "string" 11 #include "cstdlib" 12 #include "cwchar" 13 #include "cerrno" 14 #ifdef _WIN32 15 #include "support/win32/support.h" 16 #endif // _WIN32 17 18 _LIBCPP_BEGIN_NAMESPACE_STD 19 20 template class __basic_string_common<true>; 21 22 template class basic_string<char>; 23 template class basic_string<wchar_t>; 24 25 template 26 string 27 operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); 28 29 int 30 stoi(const string& str, size_t* idx, int base) 31 { 32 char* ptr; 33 const char* const p = str.c_str(); 34 typename remove_reference<decltype(errno)>::type errno_save = errno; 35 errno = 0; 36 long r = strtol(p, &ptr, base); 37 swap(errno, errno_save); 38 #ifndef _LIBCPP_NO_EXCEPTIONS 39 if (errno_save == ERANGE || r < numeric_limits<int>::min() || 40 numeric_limits<int>::max() < r) 41 throw out_of_range("stoi: out of range"); 42 if (ptr == p) 43 throw invalid_argument("stoi: no conversion"); 44 #endif // _LIBCPP_NO_EXCEPTIONS 45 if (idx) 46 *idx = static_cast<size_t>(ptr - p); 47 return static_cast<int>(r); 48 } 49 50 int 51 stoi(const wstring& str, size_t* idx, int base) 52 { 53 wchar_t* ptr; 54 const wchar_t* const p = str.c_str(); 55 typename remove_reference<decltype(errno)>::type errno_save = errno; 56 errno = 0; 57 long r = wcstol(p, &ptr, base); 58 swap(errno, errno_save); 59 #ifndef _LIBCPP_NO_EXCEPTIONS 60 if (errno_save == ERANGE || r < numeric_limits<int>::min() || 61 numeric_limits<int>::max() < r) 62 throw out_of_range("stoi: out of range"); 63 if (ptr == p) 64 throw invalid_argument("stoi: no conversion"); 65 #endif // _LIBCPP_NO_EXCEPTIONS 66 if (idx) 67 *idx = static_cast<size_t>(ptr - p); 68 return static_cast<int>(r); 69 } 70 71 long 72 stol(const string& str, size_t* idx, int base) 73 { 74 char* ptr; 75 const char* const p = str.c_str(); 76 typename remove_reference<decltype(errno)>::type errno_save = errno; 77 errno = 0; 78 long r = strtol(p, &ptr, base); 79 swap(errno, errno_save); 80 #ifndef _LIBCPP_NO_EXCEPTIONS 81 if (errno_save == ERANGE) 82 throw out_of_range("stol: out of range"); 83 if (ptr == p) 84 throw invalid_argument("stol: no conversion"); 85 #endif // _LIBCPP_NO_EXCEPTIONS 86 if (idx) 87 *idx = static_cast<size_t>(ptr - p); 88 return r; 89 } 90 91 long 92 stol(const wstring& str, size_t* idx, int base) 93 { 94 wchar_t* ptr; 95 const wchar_t* const p = str.c_str(); 96 typename remove_reference<decltype(errno)>::type errno_save = errno; 97 errno = 0; 98 long r = wcstol(p, &ptr, base); 99 swap(errno, errno_save); 100 #ifndef _LIBCPP_NO_EXCEPTIONS 101 if (errno_save == ERANGE) 102 throw out_of_range("stol: out of range"); 103 if (ptr == p) 104 throw invalid_argument("stol: no conversion"); 105 #endif // _LIBCPP_NO_EXCEPTIONS 106 if (idx) 107 *idx = static_cast<size_t>(ptr - p); 108 return r; 109 } 110 111 unsigned long 112 stoul(const string& str, size_t* idx, int base) 113 { 114 char* ptr; 115 const char* const p = str.c_str(); 116 typename remove_reference<decltype(errno)>::type errno_save = errno; 117 errno = 0; 118 unsigned long r = strtoul(p, &ptr, base); 119 swap(errno, errno_save); 120 #ifndef _LIBCPP_NO_EXCEPTIONS 121 if (errno_save == ERANGE) 122 throw out_of_range("stoul: out of range"); 123 if (ptr == p) 124 throw invalid_argument("stoul: no conversion"); 125 #endif // _LIBCPP_NO_EXCEPTIONS 126 if (idx) 127 *idx = static_cast<size_t>(ptr - p); 128 return r; 129 } 130 131 unsigned long 132 stoul(const wstring& str, size_t* idx, int base) 133 { 134 wchar_t* ptr; 135 const wchar_t* const p = str.c_str(); 136 typename remove_reference<decltype(errno)>::type errno_save = errno; 137 errno = 0; 138 unsigned long r = wcstoul(p, &ptr, base); 139 swap(errno, errno_save); 140 #ifndef _LIBCPP_NO_EXCEPTIONS 141 if (errno_save == ERANGE) 142 throw out_of_range("stoul: out of range"); 143 if (ptr == p) 144 throw invalid_argument("stoul: no conversion"); 145 #endif // _LIBCPP_NO_EXCEPTIONS 146 if (idx) 147 *idx = static_cast<size_t>(ptr - p); 148 return r; 149 } 150 151 long long 152 stoll(const string& str, size_t* idx, int base) 153 { 154 char* ptr; 155 const char* const p = str.c_str(); 156 typename remove_reference<decltype(errno)>::type errno_save = errno; 157 errno = 0; 158 long long r = strtoll(p, &ptr, base); 159 swap(errno, errno_save); 160 #ifndef _LIBCPP_NO_EXCEPTIONS 161 if (errno_save == ERANGE) 162 throw out_of_range("stoll: out of range"); 163 if (ptr == p) 164 throw invalid_argument("stoll: no conversion"); 165 #endif // _LIBCPP_NO_EXCEPTIONS 166 if (idx) 167 *idx = static_cast<size_t>(ptr - p); 168 return r; 169 } 170 171 long long 172 stoll(const wstring& str, size_t* idx, int base) 173 { 174 wchar_t* ptr; 175 const wchar_t* const p = str.c_str(); 176 typename remove_reference<decltype(errno)>::type errno_save = errno; 177 errno = 0; 178 long long r = wcstoll(p, &ptr, base); 179 swap(errno, errno_save); 180 #ifndef _LIBCPP_NO_EXCEPTIONS 181 if (errno_save == ERANGE) 182 throw out_of_range("stoll: out of range"); 183 if (ptr == p) 184 throw invalid_argument("stoll: no conversion"); 185 #endif // _LIBCPP_NO_EXCEPTIONS 186 if (idx) 187 *idx = static_cast<size_t>(ptr - p); 188 return r; 189 } 190 191 unsigned long long 192 stoull(const string& str, size_t* idx, int base) 193 { 194 char* ptr; 195 const char* const p = str.c_str(); 196 typename remove_reference<decltype(errno)>::type errno_save = errno; 197 errno = 0; 198 unsigned long long r = strtoull(p, &ptr, base); 199 swap(errno, errno_save); 200 #ifndef _LIBCPP_NO_EXCEPTIONS 201 if (errno_save == ERANGE) 202 throw out_of_range("stoull: out of range"); 203 if (ptr == p) 204 throw invalid_argument("stoull: no conversion"); 205 #endif // _LIBCPP_NO_EXCEPTIONS 206 if (idx) 207 *idx = static_cast<size_t>(ptr - p); 208 return r; 209 } 210 211 unsigned long long 212 stoull(const wstring& str, size_t* idx, int base) 213 { 214 wchar_t* ptr; 215 const wchar_t* const p = str.c_str(); 216 typename remove_reference<decltype(errno)>::type errno_save = errno; 217 errno = 0; 218 unsigned long long r = wcstoull(p, &ptr, base); 219 swap(errno, errno_save); 220 #ifndef _LIBCPP_NO_EXCEPTIONS 221 if (errno_save == ERANGE) 222 throw out_of_range("stoull: out of range"); 223 if (ptr == p) 224 throw invalid_argument("stoull: no conversion"); 225 #endif // _LIBCPP_NO_EXCEPTIONS 226 if (idx) 227 *idx = static_cast<size_t>(ptr - p); 228 return r; 229 } 230 231 float 232 stof(const string& str, size_t* idx) 233 { 234 char* ptr; 235 const char* const p = str.c_str(); 236 typename remove_reference<decltype(errno)>::type errno_save = errno; 237 errno = 0; 238 float r = strtof(p, &ptr); 239 swap(errno, errno_save); 240 #ifndef _LIBCPP_NO_EXCEPTIONS 241 if (errno_save == ERANGE) 242 throw out_of_range("stof: out of range"); 243 if (ptr == p) 244 throw invalid_argument("stof: no conversion"); 245 #endif // _LIBCPP_NO_EXCEPTIONS 246 if (idx) 247 *idx = static_cast<size_t>(ptr - p); 248 return r; 249 } 250 251 float 252 stof(const wstring& str, size_t* idx) 253 { 254 wchar_t* ptr; 255 const wchar_t* const p = str.c_str(); 256 typename remove_reference<decltype(errno)>::type errno_save = errno; 257 errno = 0; 258 float r = wcstof(p, &ptr); 259 swap(errno, errno_save); 260 #ifndef _LIBCPP_NO_EXCEPTIONS 261 if (errno_save == ERANGE) 262 throw out_of_range("stof: out of range"); 263 if (ptr == p) 264 throw invalid_argument("stof: no conversion"); 265 #endif // _LIBCPP_NO_EXCEPTIONS 266 if (idx) 267 *idx = static_cast<size_t>(ptr - p); 268 return r; 269 } 270 271 double 272 stod(const string& str, size_t* idx) 273 { 274 char* ptr; 275 const char* const p = str.c_str(); 276 typename remove_reference<decltype(errno)>::type errno_save = errno; 277 errno = 0; 278 double r = strtod(p, &ptr); 279 swap(errno, errno_save); 280 #ifndef _LIBCPP_NO_EXCEPTIONS 281 if (errno_save == ERANGE) 282 throw out_of_range("stod: out of range"); 283 if (ptr == p) 284 throw invalid_argument("stod: no conversion"); 285 #endif // _LIBCPP_NO_EXCEPTIONS 286 if (idx) 287 *idx = static_cast<size_t>(ptr - p); 288 return r; 289 } 290 291 double 292 stod(const wstring& str, size_t* idx) 293 { 294 wchar_t* ptr; 295 const wchar_t* const p = str.c_str(); 296 typename remove_reference<decltype(errno)>::type errno_save = errno; 297 errno = 0; 298 double r = wcstod(p, &ptr); 299 swap(errno, errno_save); 300 #ifndef _LIBCPP_NO_EXCEPTIONS 301 if (errno_save == ERANGE) 302 throw out_of_range("stod: out of range"); 303 if (ptr == p) 304 throw invalid_argument("stod: no conversion"); 305 #endif // _LIBCPP_NO_EXCEPTIONS 306 if (idx) 307 *idx = static_cast<size_t>(ptr - p); 308 return r; 309 } 310 311 long double 312 stold(const string& str, size_t* idx) 313 { 314 char* ptr; 315 const char* const p = str.c_str(); 316 typename remove_reference<decltype(errno)>::type errno_save = errno; 317 errno = 0; 318 long double r = strtold(p, &ptr); 319 swap(errno, errno_save); 320 #ifndef _LIBCPP_NO_EXCEPTIONS 321 if (errno_save == ERANGE) 322 throw out_of_range("stold: out of range"); 323 if (ptr == p) 324 throw invalid_argument("stold: no conversion"); 325 #endif // _LIBCPP_NO_EXCEPTIONS 326 if (idx) 327 *idx = static_cast<size_t>(ptr - p); 328 return r; 329 } 330 331 long double 332 stold(const wstring& str, size_t* idx) 333 { 334 wchar_t* ptr; 335 const wchar_t* const p = str.c_str(); 336 typename remove_reference<decltype(errno)>::type errno_save = errno; 337 errno = 0; 338 long double r = wcstold(p, &ptr); 339 swap(errno, errno_save); 340 #ifndef _LIBCPP_NO_EXCEPTIONS 341 if (errno_save == ERANGE) 342 throw out_of_range("stold: out of range"); 343 if (ptr == p) 344 throw invalid_argument("stold: no conversion"); 345 #endif // _LIBCPP_NO_EXCEPTIONS 346 if (idx) 347 *idx = static_cast<size_t>(ptr - p); 348 return r; 349 } 350 351 string to_string(int val) 352 { 353 string s; 354 s.resize(s.capacity()); 355 while (true) 356 { 357 size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%d", val)); 358 if (n2 <= s.size()) 359 { 360 s.resize(n2); 361 break; 362 } 363 s.resize(n2); 364 } 365 return s; 366 } 367 368 string to_string(unsigned val) 369 { 370 string s; 371 s.resize(s.capacity()); 372 while (true) 373 { 374 size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%u", val)); 375 if (n2 <= s.size()) 376 { 377 s.resize(n2); 378 break; 379 } 380 s.resize(n2); 381 } 382 return s; 383 } 384 385 string to_string(long val) 386 { 387 string s; 388 s.resize(s.capacity()); 389 while (true) 390 { 391 size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%ld", val)); 392 if (n2 <= s.size()) 393 { 394 s.resize(n2); 395 break; 396 } 397 s.resize(n2); 398 } 399 return s; 400 } 401 402 string to_string(unsigned long val) 403 { 404 string s; 405 s.resize(s.capacity()); 406 while (true) 407 { 408 size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%lu", val)); 409 if (n2 <= s.size()) 410 { 411 s.resize(n2); 412 break; 413 } 414 s.resize(n2); 415 } 416 return s; 417 } 418 419 string to_string(long long val) 420 { 421 string s; 422 s.resize(s.capacity()); 423 while (true) 424 { 425 size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%lld", val)); 426 if (n2 <= s.size()) 427 { 428 s.resize(n2); 429 break; 430 } 431 s.resize(n2); 432 } 433 return s; 434 } 435 436 string to_string(unsigned long long val) 437 { 438 string s; 439 s.resize(s.capacity()); 440 while (true) 441 { 442 size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%llu", val)); 443 if (n2 <= s.size()) 444 { 445 s.resize(n2); 446 break; 447 } 448 s.resize(n2); 449 } 450 return s; 451 } 452 453 string to_string(float val) 454 { 455 string s; 456 s.resize(s.capacity()); 457 while (true) 458 { 459 size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%f", val)); 460 if (n2 <= s.size()) 461 { 462 s.resize(n2); 463 break; 464 } 465 s.resize(n2); 466 } 467 return s; 468 } 469 470 string to_string(double val) 471 { 472 string s; 473 s.resize(s.capacity()); 474 while (true) 475 { 476 size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%f", val)); 477 if (n2 <= s.size()) 478 { 479 s.resize(n2); 480 break; 481 } 482 s.resize(n2); 483 } 484 return s; 485 } 486 487 string to_string(long double val) 488 { 489 string s; 490 s.resize(s.capacity()); 491 while (true) 492 { 493 size_t n2 = static_cast<size_t>(snprintf(&s[0], s.size()+1, "%Lf", val)); 494 if (n2 <= s.size()) 495 { 496 s.resize(n2); 497 break; 498 } 499 s.resize(n2); 500 } 501 return s; 502 } 503 504 wstring to_wstring(int val) 505 { 506 const size_t n = (numeric_limits<int>::digits / 3) 507 + ((numeric_limits<int>::digits % 3) != 0) 508 + 1; 509 wstring s(n, wchar_t()); 510 s.resize(s.capacity()); 511 while (true) 512 { 513 int n2 = swprintf(&s[0], s.size()+1, L"%d", val); 514 if (n2 > 0) 515 { 516 s.resize(static_cast<size_t>(n2)); 517 break; 518 } 519 s.resize(2*s.size()); 520 s.resize(s.capacity()); 521 } 522 return s; 523 } 524 525 wstring to_wstring(unsigned val) 526 { 527 const size_t n = (numeric_limits<unsigned>::digits / 3) 528 + ((numeric_limits<unsigned>::digits % 3) != 0) 529 + 1; 530 wstring s(n, wchar_t()); 531 s.resize(s.capacity()); 532 while (true) 533 { 534 int n2 = swprintf(&s[0], s.size()+1, L"%u", val); 535 if (n2 > 0) 536 { 537 s.resize(static_cast<size_t>(n2)); 538 break; 539 } 540 s.resize(2*s.size()); 541 s.resize(s.capacity()); 542 } 543 return s; 544 } 545 546 wstring to_wstring(long val) 547 { 548 const size_t n = (numeric_limits<long>::digits / 3) 549 + ((numeric_limits<long>::digits % 3) != 0) 550 + 1; 551 wstring s(n, wchar_t()); 552 s.resize(s.capacity()); 553 while (true) 554 { 555 int n2 = swprintf(&s[0], s.size()+1, L"%ld", val); 556 if (n2 > 0) 557 { 558 s.resize(static_cast<size_t>(n2)); 559 break; 560 } 561 s.resize(2*s.size()); 562 s.resize(s.capacity()); 563 } 564 return s; 565 } 566 567 wstring to_wstring(unsigned long val) 568 { 569 const size_t n = (numeric_limits<unsigned long>::digits / 3) 570 + ((numeric_limits<unsigned long>::digits % 3) != 0) 571 + 1; 572 wstring s(n, wchar_t()); 573 s.resize(s.capacity()); 574 while (true) 575 { 576 int n2 = swprintf(&s[0], s.size()+1, L"%lu", val); 577 if (n2 > 0) 578 { 579 s.resize(static_cast<size_t>(n2)); 580 break; 581 } 582 s.resize(2*s.size()); 583 s.resize(s.capacity()); 584 } 585 return s; 586 } 587 588 wstring to_wstring(long long val) 589 { 590 const size_t n = (numeric_limits<long long>::digits / 3) 591 + ((numeric_limits<long long>::digits % 3) != 0) 592 + 1; 593 wstring s(n, wchar_t()); 594 s.resize(s.capacity()); 595 while (true) 596 { 597 int n2 = swprintf(&s[0], s.size()+1, L"%lld", val); 598 if (n2 > 0) 599 { 600 s.resize(static_cast<size_t>(n2)); 601 break; 602 } 603 s.resize(2*s.size()); 604 s.resize(s.capacity()); 605 } 606 return s; 607 } 608 609 wstring to_wstring(unsigned long long val) 610 { 611 const size_t n = (numeric_limits<unsigned long long>::digits / 3) 612 + ((numeric_limits<unsigned long long>::digits % 3) != 0) 613 + 1; 614 wstring s(n, wchar_t()); 615 s.resize(s.capacity()); 616 while (true) 617 { 618 int n2 = swprintf(&s[0], s.size()+1, L"%llu", val); 619 if (n2 > 0) 620 { 621 s.resize(static_cast<size_t>(n2)); 622 break; 623 } 624 s.resize(2*s.size()); 625 s.resize(s.capacity()); 626 } 627 return s; 628 } 629 630 wstring to_wstring(float val) 631 { 632 const size_t n = 20; 633 wstring s(n, wchar_t()); 634 s.resize(s.capacity()); 635 while (true) 636 { 637 int n2 = swprintf(&s[0], s.size()+1, L"%f", val); 638 if (n2 > 0) 639 { 640 s.resize(static_cast<size_t>(n2)); 641 break; 642 } 643 s.resize(2*s.size()); 644 s.resize(s.capacity()); 645 } 646 return s; 647 } 648 649 wstring to_wstring(double val) 650 { 651 const size_t n = 20; 652 wstring s(n, wchar_t()); 653 s.resize(s.capacity()); 654 while (true) 655 { 656 int n2 = swprintf(&s[0], s.size()+1, L"%f", val); 657 if (n2 > 0) 658 { 659 s.resize(static_cast<size_t>(n2)); 660 break; 661 } 662 s.resize(2*s.size()); 663 s.resize(s.capacity()); 664 } 665 return s; 666 } 667 668 wstring to_wstring(long double val) 669 { 670 const size_t n = 20; 671 wstring s(n, wchar_t()); 672 s.resize(s.capacity()); 673 while (true) 674 { 675 int n2 = swprintf(&s[0], s.size()+1, L"%Lf", val); 676 if (n2 > 0) 677 { 678 s.resize(static_cast<size_t>(n2)); 679 break; 680 } 681 s.resize(2*s.size()); 682 s.resize(s.capacity()); 683 } 684 return s; 685 } 686 687 _LIBCPP_END_NAMESPACE_STD 688