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