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