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