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