1 // 2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 // Official repository: https://github.com/boostorg/json 8 // 9 10 // Test that header file is self-contained. 11 #include <boost/json/string.hpp> 12 13 #include <boost/json/monotonic_resource.hpp> 14 #include <boost/json/parse.hpp> 15 16 #include <numeric> 17 #include <sstream> 18 #include <string> 19 #include <stdint.h> 20 #include <unordered_set> 21 22 #include "test.hpp" 23 #include "test_suite.hpp" 24 25 BOOST_JSON_NS_BEGIN 26 27 BOOST_STATIC_ASSERT( std::is_nothrow_destructible<string>::value ); 28 BOOST_STATIC_ASSERT( std::is_nothrow_move_constructible<string>::value ); 29 30 class string_test 31 { 32 public: 33 34 #if BOOST_JSON_ARCH == 64 35 # define INIT1 { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n' } 36 # define INIT2 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' } 37 #elif BOOST_JSON_ARCH == 32 38 # define INIT1 { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } 39 # define INIT2 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K' } 40 #else 41 # error Unknown architecture 42 #endif 43 44 struct test_vectors 45 { 46 // fit in sbo 47 string_view v1; // "abc... 48 49 // dynamic alloc 50 string_view v2; // "ABC... 51 52 std::string const s1; 53 std::string const s2; 54 test_vectorsstring_test::test_vectors55 test_vectors() 56 : s1([&] 57 { 58 std::string s; 59 s.resize(string{}.capacity()); 60 std::iota(s.begin(), s.end(), 'a'); 61 return s; 62 }()) 63 , s2([&] __anon31acec7e0202string_test::test_vectors64 { 65 std::string s; 66 s.resize(string{}.capacity() + 1); 67 std::iota(s.begin(), s.end(), 'A'); 68 return s; 69 }()) 70 { 71 v1 = s1; 72 v2 = s2; 73 74 BOOST_TEST(std::string(INIT1) == s1); 75 BOOST_TEST(std::string(INIT2) == s2); 76 } 77 }; 78 79 static 80 string_view last_of(string_view s,std::size_t n)81 last_of( 82 string_view s, 83 std::size_t n) 84 { 85 return s.substr(s.size() - n); 86 } 87 88 void testConstruction()89 testConstruction() 90 { 91 test_vectors const t; 92 93 // string() 94 { 95 string s; 96 } 97 98 // string(storage_ptr) 99 { 100 auto const sp = 101 make_shared_resource<unique_resource>(); 102 string s(sp); 103 BOOST_TEST(s.empty()); 104 BOOST_TEST(*s.storage() == *sp.get()); 105 } 106 107 // string(size_type, char, storage_ptr) 108 { 109 fail_loop([&](storage_ptr const& sp) 110 { 111 string s(t.v1.size(), '*', sp); 112 BOOST_TEST(s == std::string(t.v1.size(), '*')); 113 }); 114 115 { 116 string s(t.v2.size(), '*'); 117 BOOST_TEST(s == std::string(t.v2.size(), '*')); 118 } 119 } 120 121 // string(char const*, storage_ptr) 122 { 123 fail_loop([&](storage_ptr const& sp) 124 { 125 string s(t.s1.c_str(), sp); 126 BOOST_TEST(s == t.v1); 127 }); 128 129 fail_loop([&](storage_ptr const& sp) 130 { 131 string s(t.s2.c_str(), sp); 132 BOOST_TEST(s == t.v2); 133 }); 134 135 { 136 string s(t.s1.c_str()); 137 BOOST_TEST(s == t.v1); 138 } 139 140 { 141 string s(t.s2.c_str()); 142 BOOST_TEST(s == t.v2); 143 } 144 } 145 146 // string(char const*, size_type, storage_ptr) 147 { 148 fail_loop([&](storage_ptr const& sp) 149 { 150 string s(t.s1.c_str(), 3, sp); 151 BOOST_TEST(s == "abc"); 152 }); 153 154 fail_loop([&](storage_ptr const& sp) 155 { 156 string s(t.s2.c_str(), 3, sp); 157 BOOST_TEST(s == "ABC"); 158 }); 159 160 { 161 string s(t.s1.c_str(), 3); 162 BOOST_TEST(s == "abc"); 163 } 164 165 { 166 string s(t.s2.c_str(), 3); 167 BOOST_TEST(s == "ABC"); 168 } 169 } 170 171 // string(InputIt, InputIt, storage_ptr) 172 { 173 fail_loop([&](storage_ptr const& sp) 174 { 175 string s(t.v1.begin(), t.v1.end(), sp); 176 BOOST_TEST(s == t.v1); 177 }); 178 179 fail_loop([&](storage_ptr const& sp) 180 { 181 string s(t.v2.begin(), t.v2.end(), sp); 182 BOOST_TEST(s == t.v2); 183 }); 184 185 fail_loop([&](storage_ptr const& sp) 186 { 187 string s( 188 make_input_iterator(t.v1.begin()), 189 make_input_iterator(t.v1.end()), sp); 190 BOOST_TEST(s == t.v1); 191 }); 192 193 fail_loop([&](storage_ptr const& sp) 194 { 195 string s( 196 make_input_iterator(t.v2.begin()), 197 make_input_iterator(t.v2.end()), sp); 198 BOOST_TEST(s == t.v2); 199 }); 200 201 { 202 string s(t.v1.begin(), t.v1.end()); 203 BOOST_TEST(s == t.v1); 204 } 205 206 { 207 string s(t.v2.begin(), t.v2.end()); 208 BOOST_TEST(s == t.v2); 209 } 210 211 { 212 string s( 213 make_input_iterator(t.v1.begin()), 214 make_input_iterator(t.v1.end())); 215 BOOST_TEST(s == t.v1); 216 } 217 218 { 219 string s( 220 make_input_iterator(t.v2.begin()), 221 make_input_iterator(t.v2.end())); 222 BOOST_TEST(s == t.v2); 223 } 224 } 225 226 // string(string) 227 { 228 { 229 string const s0(t.v1); 230 string s(s0); 231 BOOST_TEST(s == t.v1); 232 } 233 234 { 235 string const s0(t.v2); 236 string s(s0); 237 BOOST_TEST(s == t.v2); 238 } 239 } 240 241 // string(string, storage_ptr) 242 { 243 fail_loop([&](storage_ptr const& sp) 244 { 245 string const s0(t.v1); 246 string s(s0, sp); 247 BOOST_TEST(s == t.v1); 248 }); 249 250 fail_loop([&](storage_ptr const& sp) 251 { 252 string const s0(t.v2); 253 string s(s0, sp); 254 BOOST_TEST(s == t.v2); 255 }); 256 } 257 258 // string(pilfered<string>) 259 { 260 { 261 string s1(t.v1); 262 string s2(pilfer(s1)); 263 BOOST_TEST(s2 == t.v1); 264 BOOST_TEST(s1.empty()); 265 BOOST_TEST( 266 s1.storage() == storage_ptr()); 267 } 268 269 { 270 string s1(t.v2); 271 string s2(pilfer(s1)); 272 BOOST_TEST(s2 == t.v2); 273 BOOST_TEST(s1.empty()); 274 BOOST_TEST( 275 s1.storage() == storage_ptr()); 276 } 277 278 // ensure pilfered-from objects 279 // are trivially destructible 280 { 281 string s1(make_shared_resource< 282 monotonic_resource>()); 283 string s2(pilfer(s1)); 284 BOOST_TEST(s1.storage().get() == 285 storage_ptr().get()); 286 } 287 } 288 289 // string(string&&) 290 { 291 { 292 string s1(t.v1); 293 string s2(std::move(s1)); 294 BOOST_TEST(s2 == t.v1); 295 BOOST_TEST(s1.empty()); 296 BOOST_TEST( 297 *s1.storage() == 298 *s2.storage()); 299 } 300 301 { 302 string s1(t.v2); 303 string s2(std::move(s1)); 304 BOOST_TEST(s2 == t.v2); 305 BOOST_TEST(s1.empty()); 306 BOOST_TEST( 307 *s1.storage() == 308 *s2.storage()); 309 } 310 } 311 312 // string(string&&, storage_ptr) 313 { 314 // same storage 315 316 fail_loop([&](storage_ptr const& sp) 317 { 318 string s1(t.v1, sp); 319 string s2(std::move(s1), sp); 320 BOOST_TEST(s2 == t.v1); 321 BOOST_TEST(s1.empty()); 322 BOOST_TEST( 323 *s1.storage() == 324 *s2.storage()); 325 }); 326 327 fail_loop([&](storage_ptr const& sp) 328 { 329 string s1(t.v2, sp); 330 string s2(std::move(s1)); 331 BOOST_TEST(s2 == t.v2); 332 BOOST_TEST(s1.empty()); 333 BOOST_TEST( 334 *s1.storage() == 335 *s2.storage()); 336 }); 337 338 // different storage 339 340 fail_loop([&](storage_ptr const& sp) 341 { 342 string s1(t.v1); 343 string s2(std::move(s1), sp); 344 BOOST_TEST(s2 == t.v1); 345 BOOST_TEST(s1 == t.v1); 346 BOOST_TEST( 347 *s1.storage() != 348 *s2.storage()); 349 }); 350 351 fail_loop([&](storage_ptr const& sp) 352 { 353 string s1(t.v2); 354 string s2(std::move(s1), sp); 355 BOOST_TEST(s2 == t.v2); 356 BOOST_TEST(s1 == t.v2); 357 BOOST_TEST( 358 *s1.storage() != 359 *s2.storage()); 360 }); 361 } 362 363 // string(string_view, storage_ptr) 364 { 365 fail_loop([&](storage_ptr const& sp) 366 { 367 string s(t.v1, sp); 368 BOOST_TEST(s == t.v1); 369 }); 370 371 fail_loop([&](storage_ptr const& sp) 372 { 373 string s(t.v2, sp); 374 BOOST_TEST(s == t.v2); 375 }); 376 377 { 378 string s(t.v1); 379 BOOST_TEST(s == t.v1); 380 } 381 382 { 383 string s(t.v2); 384 BOOST_TEST(s == t.v2); 385 } 386 } 387 } 388 389 void testAssignment()390 testAssignment() 391 { 392 test_vectors const t; 393 394 // operator=(string) 395 { 396 fail_loop([&](storage_ptr const& sp) 397 { 398 std::string c(t.v1.size(), '*'); 399 string s(c, sp); 400 string const s2(t.v1); 401 s = s2; 402 BOOST_TEST(s == t.v1); 403 }); 404 405 fail_loop([&](storage_ptr const& sp) 406 { 407 std::string c(t.v2.size(), '*'); 408 string s(c, sp); 409 string const s2(t.v1); 410 s = s2; 411 BOOST_TEST(s == t.v1); 412 }); 413 414 fail_loop([&](storage_ptr const& sp) 415 { 416 std::string c(t.v1.size(), '*'); 417 string s(c, sp); 418 string const s2(t.v2); 419 s = s2; 420 BOOST_TEST(s == t.v2); 421 }); 422 423 fail_loop([&](storage_ptr const& sp) 424 { 425 std::string c(t.v2.size(), '*'); 426 string s(c, sp); 427 string const s2(t.v2); 428 s = s2; 429 BOOST_TEST(s == t.v2); 430 }); 431 } 432 433 // operator=(string&&) 434 { 435 // same storage 436 437 fail_loop([&](storage_ptr const& sp) 438 { 439 std::string c(t.v1.size(), '*'); 440 string s(c, sp); 441 string s2(t.v1, sp); 442 s = std::move(s2); 443 BOOST_TEST(s == t.v1); 444 BOOST_TEST(s2.empty()); 445 BOOST_TEST( 446 *s.storage() == 447 *s2.storage()); 448 }); 449 450 fail_loop([&](storage_ptr const& sp) 451 { 452 std::string c(t.v2.size(), '*'); 453 string s(c, sp); 454 string s2(t.v1, sp); 455 s = std::move(s2); 456 BOOST_TEST(s == t.v1); 457 BOOST_TEST(s2.empty()); 458 BOOST_TEST( 459 *s.storage() == 460 *s2.storage()); 461 }); 462 463 fail_loop([&](storage_ptr const& sp) 464 { 465 std::string c(t.v1.size(), '*'); 466 string s(c, sp); 467 string s2(t.v2, sp); 468 s = std::move(s2); 469 BOOST_TEST(s == t.v2); 470 BOOST_TEST(s2.empty()); 471 BOOST_TEST( 472 *s.storage() == 473 *s2.storage()); 474 }); 475 476 fail_loop([&](storage_ptr const& sp) 477 { 478 std::string c(t.v2.size(), '*'); 479 string s(c, sp); 480 string s2(t.v2, sp); 481 s = std::move(s2); 482 BOOST_TEST(s == t.v2); 483 BOOST_TEST(s2.empty()); 484 BOOST_TEST( 485 *s.storage() == 486 *s2.storage()); 487 }); 488 489 // different storage 490 491 fail_loop([&](storage_ptr const& sp) 492 { 493 std::string c(t.v1.size(), '*'); 494 string s(c, sp); 495 string s2(t.v1); 496 s = std::move(s2); 497 BOOST_TEST(s == t.v1); 498 BOOST_TEST(s2 == t.v1); 499 BOOST_TEST( 500 *s.storage() != 501 *s2.storage()); 502 }); 503 504 fail_loop([&](storage_ptr const& sp) 505 { 506 std::string c(t.v2.size(), '*'); 507 string s(c, sp); 508 string s2(t.v1); 509 s = std::move(s2); 510 BOOST_TEST(s == t.v1); 511 BOOST_TEST(s2 == t.v1); 512 BOOST_TEST( 513 *s.storage() != 514 *s2.storage()); 515 }); 516 517 fail_loop([&](storage_ptr const& sp) 518 { 519 std::string c(t.v1.size(), '*'); 520 string s(c, sp); 521 string s2(t.v2); 522 s = std::move(s2); 523 BOOST_TEST(s == t.v2); 524 BOOST_TEST(s2 == t.v2); 525 BOOST_TEST( 526 *s.storage() != 527 *s2.storage()); 528 }); 529 530 fail_loop([&](storage_ptr const& sp) 531 { 532 std::string c(t.v2.size(), '*'); 533 string s(c, sp); 534 string s2(t.v2); 535 s = std::move(s2); 536 BOOST_TEST(s == t.v2); 537 BOOST_TEST(s2 == t.v2); 538 BOOST_TEST( 539 *s.storage() != 540 *s2.storage()); 541 }); 542 } 543 544 // operator=(char const*) 545 { 546 fail_loop([&](storage_ptr const& sp) 547 { 548 string s(t.v1.size(), '*', sp); 549 s = t.s1.c_str(); 550 BOOST_TEST(s == t.v1); 551 }); 552 553 fail_loop([&](storage_ptr const& sp) 554 { 555 string s(t.v2.size(), '*', sp); 556 s = t.s1.c_str(); 557 BOOST_TEST(s == t.v1); 558 }); 559 560 fail_loop([&](storage_ptr const& sp) 561 { 562 string s(t.v1.size(), '*', sp); 563 s = t.s2.c_str(); 564 BOOST_TEST(s == t.v2); 565 }); 566 567 fail_loop([&](storage_ptr const& sp) 568 { 569 string s(t.v2.size(), '*', sp); 570 s = t.s2.c_str(); 571 BOOST_TEST(s == t.v2); 572 }); 573 } 574 575 // operator=(string_view) 576 { 577 fail_loop([&](storage_ptr const& sp) 578 { 579 string s(t.v1.size(), '*', sp); 580 s = t.v1; 581 BOOST_TEST(s == t.v1); 582 }); 583 584 fail_loop([&](storage_ptr const& sp) 585 { 586 string s(t.v2.size(), '*', sp); 587 s = t.v1; 588 BOOST_TEST(s == t.v1); 589 }); 590 591 fail_loop([&](storage_ptr const& sp) 592 { 593 string s(t.v1.size(), '*', sp); 594 s = t.v2; 595 BOOST_TEST(s == t.v2); 596 }); 597 598 fail_loop([&](storage_ptr const& sp) 599 { 600 string s(t.v2.size(), '*', sp); 601 s = t.v2; 602 BOOST_TEST(s == t.v2); 603 }); 604 } 605 } 606 607 void testAssign()608 testAssign() 609 { 610 test_vectors const t; 611 612 // assign(size_type, char) 613 { 614 fail_loop([&](storage_ptr const& sp) 615 { 616 string s(t.v1.size(), 'x', sp); 617 s.assign(t.v1.size(), '*'); 618 BOOST_TEST( 619 s == std::string(t.v1.size(), '*')); 620 }); 621 622 fail_loop([&](storage_ptr const& sp) 623 { 624 string s(t.v2.size(), 'x', sp); 625 s.assign(t.v1.size(), '*'); 626 BOOST_TEST( 627 s == std::string(t.v1.size(), '*')); 628 }); 629 630 fail_loop([&](storage_ptr const& sp) 631 { 632 string s(t.v1.size(), 'x', sp); 633 s.assign(t.v2.size(), '*'); 634 BOOST_TEST( 635 s == std::string(t.v2.size(), '*')); 636 }); 637 638 fail_loop([&](storage_ptr const& sp) 639 { 640 string s(t.v2.size(), 'x', sp); 641 s.assign(t.v2.size(), '*'); 642 BOOST_TEST( 643 s == std::string(t.v2.size(), '*')); 644 }); 645 } 646 647 // assign(string) 648 { 649 fail_loop([&](storage_ptr const& sp) 650 { 651 string s(t.v1.size(), 'x', sp); 652 s.assign(string(t.v1.size(), '*')); 653 BOOST_TEST( 654 s == std::string(t.v1.size(), '*')); 655 }); 656 657 fail_loop([&](storage_ptr const& sp) 658 { 659 string s(t.v2.size(), 'x', sp); 660 s.assign(string(t.v1.size(), '*')); 661 BOOST_TEST( 662 s == std::string(t.v1.size(), '*')); 663 }); 664 665 fail_loop([&](storage_ptr const& sp) 666 { 667 string s(t.v1.size(), 'x', sp); 668 s.assign(string(t.v2.size(), '*')); 669 BOOST_TEST( 670 s == std::string(t.v2.size(), '*')); 671 }); 672 673 fail_loop([&](storage_ptr const& sp) 674 { 675 string s(t.v2.size(), 'x', sp); 676 s.assign(string(t.v2.size(), '*')); 677 BOOST_TEST( 678 s == std::string(t.v2.size(), '*')); 679 }); 680 681 // self-assign 682 { 683 string s(t.v1); 684 s = static_cast<string const&>(s); 685 BOOST_TEST(s == t.v1); 686 } 687 } 688 689 // assign(string&&) 690 { 691 // same storage 692 693 fail_loop([&](storage_ptr const& sp) 694 { 695 std::string c(t.v1.size(), '*'); 696 string s(c, sp); 697 string s2(t.v1, sp); 698 s.assign(std::move(s2)); 699 BOOST_TEST(s == t.v1); 700 BOOST_TEST(s2.empty()); 701 BOOST_TEST( 702 *s.storage() == 703 *s2.storage()); 704 }); 705 706 fail_loop([&](storage_ptr const& sp) 707 { 708 std::string c(t.v2.size(), '*'); 709 string s(c, sp); 710 string s2(t.v1, sp); 711 s.assign(std::move(s2)); 712 BOOST_TEST(s == t.v1); 713 BOOST_TEST(s2.empty()); 714 BOOST_TEST( 715 *s.storage() == 716 *s2.storage()); 717 }); 718 719 fail_loop([&](storage_ptr const& sp) 720 { 721 std::string c(t.v1.size(), '*'); 722 string s(c, sp); 723 string s2(t.v2, sp); 724 s.assign(std::move(s2)); 725 BOOST_TEST(s == t.v2); 726 BOOST_TEST(s2.empty()); 727 BOOST_TEST( 728 *s.storage() == 729 *s2.storage()); 730 }); 731 732 fail_loop([&](storage_ptr const& sp) 733 { 734 std::string c(t.v2.size(), '*'); 735 string s(c, sp); 736 string s2(t.v2, sp); 737 s.assign(std::move(s2)); 738 BOOST_TEST(s == t.v2); 739 BOOST_TEST(s2.empty()); 740 BOOST_TEST( 741 *s.storage() == 742 *s2.storage()); 743 }); 744 745 // different storage 746 747 fail_loop([&](storage_ptr const& sp) 748 { 749 std::string c(t.v1.size(), '*'); 750 string s(c, sp); 751 string s2(t.v1); 752 s.assign(std::move(s2)); 753 BOOST_TEST(s == t.v1); 754 BOOST_TEST(s2 == t.v1); 755 BOOST_TEST( 756 *s.storage() != 757 *s2.storage()); 758 }); 759 760 fail_loop([&](storage_ptr const& sp) 761 { 762 std::string c(t.v2.size(), '*'); 763 string s(c, sp); 764 string s2(t.v1); 765 s.assign(std::move(s2)); 766 BOOST_TEST(s == t.v1); 767 BOOST_TEST(s2 == t.v1); 768 BOOST_TEST( 769 *s.storage() != 770 *s2.storage()); 771 }); 772 773 fail_loop([&](storage_ptr const& sp) 774 { 775 std::string c(t.v1.size(), '*'); 776 string s(c, sp); 777 string s2(t.v2); 778 s.assign(std::move(s2)); 779 BOOST_TEST(s == t.v2); 780 BOOST_TEST(s2 == t.v2); 781 BOOST_TEST( 782 *s.storage() != 783 *s2.storage()); 784 }); 785 786 fail_loop([&](storage_ptr const& sp) 787 { 788 std::string c(t.v2.size(), '*'); 789 string s(c, sp); 790 string s2(t.v2); 791 s.assign(std::move(s2)); 792 BOOST_TEST(s == t.v2); 793 BOOST_TEST(s2 == t.v2); 794 BOOST_TEST( 795 *s.storage() != 796 *s2.storage()); 797 }); 798 } 799 800 // assign(char const*, size_type) 801 { 802 fail_loop([&](storage_ptr const& sp) 803 { 804 string s(t.v1.size(), '*', sp); 805 s.assign(t.s1.c_str(), 3); 806 BOOST_TEST(s == "abc"); 807 }); 808 809 fail_loop([&](storage_ptr const& sp) 810 { 811 string s(t.v2.size(), '*', sp); 812 s.assign(t.s1.c_str(), 3); 813 BOOST_TEST(s == "abc"); 814 }); 815 816 fail_loop([&](storage_ptr const& sp) 817 { 818 string s(t.v1.size(), '*', sp); 819 s.assign(t.s2.c_str(), 3); 820 BOOST_TEST(s == "ABC"); 821 }); 822 823 fail_loop([&](storage_ptr const& sp) 824 { 825 string s(t.v2.size(), '*', sp); 826 s.assign(t.s2.c_str(), 3); 827 BOOST_TEST(s == "ABC"); 828 }); 829 }; 830 831 // assign(char const* s) 832 { 833 fail_loop([&](storage_ptr const& sp) 834 { 835 string s(t.v1.size(), '*', sp); 836 s.assign(t.s1.c_str()); 837 BOOST_TEST(s == t.v1); 838 }); 839 840 fail_loop([&](storage_ptr const& sp) 841 { 842 string s(t.v2.size(), '*', sp); 843 s.assign(t.s1.c_str()); 844 BOOST_TEST(s == t.v1); 845 }); 846 847 fail_loop([&](storage_ptr const& sp) 848 { 849 string s(t.v1.size(), '*', sp); 850 s.assign(t.s2.c_str()); 851 BOOST_TEST(s == t.v2); 852 }); 853 854 fail_loop([&](storage_ptr const& sp) 855 { 856 string s(t.v2.size(), '*', sp); 857 s.assign(t.s2.c_str()); 858 BOOST_TEST(s == t.v2); 859 }); 860 } 861 862 // assign(InputIt, InputIt) 863 { 864 fail_loop([&](storage_ptr const& sp) 865 { 866 string s(t.v1.size(), '*', sp); 867 s.assign(t.s1.begin(), t.s1.end()); 868 BOOST_TEST(s == t.v1); 869 }); 870 871 fail_loop([&](storage_ptr const& sp) 872 { 873 string s(t.v2.size(), '*', sp); 874 s.assign(t.s1.begin(), t.s1.end()); 875 BOOST_TEST(s == t.v1); 876 }); 877 878 fail_loop([&](storage_ptr const& sp) 879 { 880 string s(t.v1.size(), '*', sp); 881 s.assign( 882 make_input_iterator(t.s1.begin()), 883 make_input_iterator(t.s1.end())); 884 BOOST_TEST(s == t.v1); 885 }); 886 887 fail_loop([&](storage_ptr const& sp) 888 { 889 string s(t.v2.size(), '*', sp); 890 s.assign( 891 make_input_iterator(t.s1.begin()), 892 make_input_iterator(t.s1.end())); 893 BOOST_TEST(s == t.v1); 894 }); 895 896 fail_loop([&](storage_ptr const& sp) 897 { 898 string s(t.v1.size(), '*', sp); 899 s.assign(t.s2.begin(), t.s2.end()); 900 BOOST_TEST(s == t.v2); 901 }); 902 903 fail_loop([&](storage_ptr const& sp) 904 { 905 string s(t.v2.size(), '*', sp); 906 s.assign(t.s2.begin(), t.s2.end()); 907 BOOST_TEST(s == t.v2); 908 }); 909 910 fail_loop([&](storage_ptr const& sp) 911 { 912 string s(t.v1.size(), '*', sp); 913 s.assign( 914 make_input_iterator(t.s2.begin()), 915 make_input_iterator(t.s2.end())); 916 BOOST_TEST(s == t.v2); 917 }); 918 919 fail_loop([&](storage_ptr const& sp) 920 { 921 string s(t.v2.size(), '*', sp); 922 s.assign( 923 make_input_iterator(t.s2.begin()), 924 make_input_iterator(t.s2.end())); 925 BOOST_TEST(s == t.v2); 926 }); 927 928 // empty range 929 { 930 string s(t.v1); 931 s.assign(t.s1.begin(), t.s1.begin()); 932 BOOST_TEST(s.empty()); 933 } 934 935 // empty range 936 { 937 string s(t.v1); 938 s.assign( 939 make_input_iterator(t.s1.begin()), 940 make_input_iterator(t.s1.begin())); 941 BOOST_TEST(s.empty()); 942 } 943 } 944 945 // assign(string_view) 946 { 947 fail_loop([&](storage_ptr const& sp) 948 { 949 string s(t.v1.size(), '*', sp); 950 s.assign(t.v1); 951 BOOST_TEST(s == t.v1); 952 }); 953 954 fail_loop([&](storage_ptr const& sp) 955 { 956 string s(t.v2.size(), '*', sp); 957 s.assign(t.v1); 958 BOOST_TEST(s == t.v1); 959 }); 960 961 fail_loop([&](storage_ptr const& sp) 962 { 963 string s(t.v1.size(), '*', sp); 964 s.assign(t.v2); 965 BOOST_TEST(s == t.v2); 966 }); 967 968 fail_loop([&](storage_ptr const& sp) 969 { 970 string s(t.v2.size(), '*', sp); 971 s.assign(t.v2); 972 BOOST_TEST(s == t.v2); 973 }); 974 } 975 } 976 977 void testElementAccess()978 testElementAccess() 979 { 980 test_vectors const t; 981 982 string s1(t.v1); 983 string s2(t.v2); 984 auto const& cs1(s1); 985 auto const& cs2(s2); 986 987 // at(size_type) 988 { 989 BOOST_TEST(s1.at(1) == 'b'); 990 s1.at(1) = '*'; 991 BOOST_TEST(s1.at(1) == '*'); 992 s1.at(1) = 'b'; 993 BOOST_TEST(s1.at(1) == 'b'); 994 995 BOOST_TEST(s2.at(1) == 'B'); 996 s2.at(1) = '*'; 997 BOOST_TEST(s2.at(1) == '*'); 998 s2.at(1) = 'B'; 999 BOOST_TEST(s2.at(1) == 'B'); 1000 1001 BOOST_TEST_THROWS(s1.at(s2.size()), 1002 std::out_of_range); 1003 } 1004 1005 // at(size_type) const 1006 { 1007 BOOST_TEST(cs1.at(1) == 'b'); 1008 BOOST_TEST(cs2.at(1) == 'B'); 1009 1010 BOOST_TEST_THROWS(cs1.at(cs2.size()), 1011 std::out_of_range); 1012 } 1013 1014 // operator[&](size_type) 1015 { 1016 BOOST_TEST(s1[1] == 'b'); 1017 s1[1] = '*'; 1018 BOOST_TEST(s1[1] == '*'); 1019 s1[1] = 'b'; 1020 BOOST_TEST(s1[1] == 'b'); 1021 1022 BOOST_TEST(s2[1] == 'B'); 1023 s2[1] = '*'; 1024 BOOST_TEST(s2[1] == '*'); 1025 s2[1] = 'B'; 1026 BOOST_TEST(s2[1] == 'B'); 1027 } 1028 1029 // operator[&](size_type) const 1030 { 1031 BOOST_TEST(cs1[1] == 'b'); 1032 BOOST_TEST(cs2[1] == 'B'); 1033 } 1034 1035 // front() 1036 { 1037 BOOST_TEST(s1.front() == 'a'); 1038 s1.front() = '*'; 1039 BOOST_TEST(s1.front() == '*'); 1040 s1.front() = 'a'; 1041 BOOST_TEST(s1.front() == 'a'); 1042 1043 BOOST_TEST(s2.front() == 'A'); 1044 s2.front() = '*'; 1045 BOOST_TEST(s2.front() == '*'); 1046 s2.front() = 'A'; 1047 BOOST_TEST(s2.front() == 'A'); 1048 } 1049 1050 // front() const 1051 { 1052 BOOST_TEST(cs1.front() == 'a'); 1053 BOOST_TEST(cs2.front() == 'A'); 1054 } 1055 1056 // back() 1057 { 1058 auto const ch1 = s1.at(s1.size()-1); 1059 auto const ch2 = s2.at(s2.size()-1); 1060 1061 BOOST_TEST(s1.back() == ch1); 1062 s1.back() = '*'; 1063 BOOST_TEST(s1.back() == '*'); 1064 s1.back() = ch1; 1065 BOOST_TEST(s1.back() == ch1); 1066 1067 BOOST_TEST(s2.back() == ch2); 1068 s2.back() = '*'; 1069 BOOST_TEST(s2.back() == '*'); 1070 s2.back() = ch2; 1071 BOOST_TEST(s2.back() == ch2); 1072 } 1073 1074 // back() const 1075 { 1076 auto const ch1 = s1.at(s1.size()-1); 1077 auto const ch2 = s2.at(s2.size()-1); 1078 1079 BOOST_TEST(cs1.back() == ch1); 1080 BOOST_TEST(cs2.back() == ch2); 1081 } 1082 1083 // data() 1084 { 1085 BOOST_TEST( 1086 string_view(s1.data()) == t.v1); 1087 BOOST_TEST( 1088 string_view(s2.data()) == t.v2); 1089 } 1090 // data() const 1091 { 1092 BOOST_TEST( 1093 string_view(cs1.data()) == t.v1); 1094 BOOST_TEST( 1095 string_view(cs2.data()) == t.v2); 1096 } 1097 1098 // c_str() 1099 { 1100 BOOST_TEST( 1101 string_view(cs1.c_str()) == t.v1); 1102 BOOST_TEST( 1103 string_view(cs2.c_str()) == t.v2); 1104 } 1105 1106 // operator string_view() 1107 { 1108 BOOST_TEST( 1109 string_view(cs1) == t.v1); 1110 BOOST_TEST( 1111 string_view(cs2) == t.v2); 1112 } 1113 } 1114 1115 void testIterators()1116 testIterators() 1117 { 1118 string s = "abc"; 1119 auto const& ac(s); 1120 1121 { 1122 auto it = s.begin(); 1123 BOOST_TEST(*it == 'a'); ++it; 1124 BOOST_TEST(*it == 'b'); it++; 1125 BOOST_TEST(*it == 'c'); ++it; 1126 BOOST_TEST(it == s.end()); 1127 } 1128 { 1129 auto it = s.cbegin(); 1130 BOOST_TEST(*it == 'a'); ++it; 1131 BOOST_TEST(*it == 'b'); it++; 1132 BOOST_TEST(*it == 'c'); ++it; 1133 BOOST_TEST(it == s.cend()); 1134 } 1135 { 1136 auto it = ac.begin(); 1137 BOOST_TEST(*it == 'a'); ++it; 1138 BOOST_TEST(*it == 'b'); it++; 1139 BOOST_TEST(*it == 'c'); ++it; 1140 BOOST_TEST(it == ac.end()); 1141 } 1142 { 1143 auto it = s.end(); 1144 --it; BOOST_TEST(*it == 'c'); 1145 it--; BOOST_TEST(*it == 'b'); 1146 --it; BOOST_TEST(*it == 'a'); 1147 BOOST_TEST(it == s.begin()); 1148 } 1149 { 1150 auto it = s.cend(); 1151 --it; BOOST_TEST(*it == 'c'); 1152 it--; BOOST_TEST(*it == 'b'); 1153 --it; BOOST_TEST(*it == 'a'); 1154 BOOST_TEST(it == s.cbegin()); 1155 } 1156 { 1157 auto it = ac.end(); 1158 --it; BOOST_TEST(*it == 'c'); 1159 it--; BOOST_TEST(*it == 'b'); 1160 --it; BOOST_TEST(*it == 'a'); 1161 BOOST_TEST(it == ac.begin()); 1162 } 1163 1164 { 1165 auto it = s.rbegin(); 1166 BOOST_TEST(*it == 'c'); ++it; 1167 BOOST_TEST(*it == 'b'); it++; 1168 BOOST_TEST(*it == 'a'); ++it; 1169 BOOST_TEST(it == s.rend()); 1170 } 1171 { 1172 auto it = s.crbegin(); 1173 BOOST_TEST(*it == 'c'); ++it; 1174 BOOST_TEST(*it == 'b'); it++; 1175 BOOST_TEST(*it == 'a'); ++it; 1176 BOOST_TEST(it == s.crend()); 1177 } 1178 { 1179 auto it = ac.rbegin(); 1180 BOOST_TEST(*it == 'c'); ++it; 1181 BOOST_TEST(*it == 'b'); it++; 1182 BOOST_TEST(*it == 'a'); ++it; 1183 BOOST_TEST(it == ac.rend()); 1184 } 1185 { 1186 auto it = s.rend(); 1187 --it; BOOST_TEST(*it == 'a'); 1188 it--; BOOST_TEST(*it == 'b'); 1189 --it; BOOST_TEST(*it == 'c'); 1190 BOOST_TEST(it == s.rbegin()); 1191 } 1192 { 1193 auto it = s.crend(); 1194 --it; BOOST_TEST(*it == 'a'); 1195 it--; BOOST_TEST(*it == 'b'); 1196 --it; BOOST_TEST(*it == 'c'); 1197 BOOST_TEST(it == s.crbegin()); 1198 } 1199 { 1200 auto it = ac.rend(); 1201 --it; BOOST_TEST(*it == 'a'); 1202 it--; BOOST_TEST(*it == 'b'); 1203 --it; BOOST_TEST(*it == 'c'); 1204 BOOST_TEST(it == ac.rbegin()); 1205 } 1206 1207 { 1208 string s2; 1209 string const& cs2(s2); 1210 BOOST_TEST(std::distance( 1211 s2.begin(), s2.end()) == 0); 1212 BOOST_TEST(std::distance( 1213 cs2.begin(), cs2.end()) == 0); 1214 BOOST_TEST(std::distance( 1215 s2.rbegin(), s2.rend()) == 0); 1216 BOOST_TEST(std::distance( 1217 cs2.rbegin(), cs2.rend()) == 0); 1218 } 1219 } 1220 1221 void testCapacity()1222 testCapacity() 1223 { 1224 test_vectors const t; 1225 1226 // empty() 1227 { 1228 { 1229 string s; 1230 BOOST_TEST(s.empty()); 1231 } 1232 { 1233 string s = "abc"; 1234 BOOST_TEST(! s.empty()); 1235 } 1236 } 1237 1238 // size() 1239 // max_size() 1240 { 1241 string s = "abc"; 1242 BOOST_TEST(s.size() == 3); 1243 BOOST_TEST(s.max_size() < string::npos); 1244 } 1245 1246 // reserve(size_type) 1247 { 1248 fail_loop([&](storage_ptr const& sp) 1249 { 1250 string s(sp); 1251 s.append(t.v1); 1252 s.append(t.v2); 1253 1254 s.reserve(0); 1255 BOOST_TEST(s.size() == 1256 t.v1.size() + t.v2.size()); 1257 1258 s.reserve(t.v1.size() + t.v2.size()); 1259 BOOST_TEST(s.size() == 1260 t.v1.size() + t.v2.size()); 1261 1262 s.reserve(s.size() * 2); 1263 BOOST_TEST(s.capacity() > 1264 t.v1.size() + t.v2.size()); 1265 1266 s.resize(t.v1.size()); 1267 s.reserve(t.v1.size()); 1268 BOOST_TEST(s == t.v1); 1269 }); 1270 } 1271 1272 // capacity() 1273 { 1274 // implied 1275 } 1276 1277 // shrink_to_fit() 1278 fail_loop([&](storage_ptr const& sp) 1279 { 1280 string s(sp); 1281 string::size_type cap; 1282 1283 cap = s.capacity(); 1284 s.shrink_to_fit(); 1285 BOOST_TEST(s.capacity() == cap); 1286 1287 s.reserve(s.capacity() + 1); 1288 s.shrink_to_fit(); 1289 BOOST_TEST(s.capacity() == cap); 1290 1291 s.resize(cap * 3, '*'); 1292 cap = s.capacity(); 1293 s.resize(cap - 1); 1294 s.shrink_to_fit(); 1295 BOOST_TEST(s.capacity() == cap); 1296 1297 s.resize(cap / 2); 1298 BOOST_TEST(s.capacity() == cap); 1299 1300 s.shrink_to_fit(); 1301 BOOST_TEST(s.capacity() < cap); 1302 }); 1303 } 1304 1305 void testClear()1306 testClear() 1307 { 1308 test_vectors const t; 1309 1310 // clear() 1311 { 1312 { 1313 string s(t.v1); 1314 s.clear(); 1315 BOOST_TEST(s.empty()); 1316 BOOST_TEST(s.size() == 0); 1317 BOOST_TEST(s.capacity() > 0); 1318 } 1319 1320 { 1321 string s(t.v2); 1322 s.clear(); 1323 BOOST_TEST(s.empty()); 1324 BOOST_TEST(s.size() == 0); 1325 BOOST_TEST(s.capacity() > 0); 1326 } 1327 } 1328 } 1329 1330 void testInsert()1331 testInsert() 1332 { 1333 test_vectors const t; 1334 1335 // insert(size_type, size_type, char) 1336 { 1337 fail_loop([&](storage_ptr const& sp) 1338 { 1339 string s(t.v1, sp); 1340 s.insert(1, 3, '*'); 1341 BOOST_TEST(s == std::string( 1342 t.v1).insert(1, 3, '*')); 1343 }); 1344 1345 fail_loop([&](storage_ptr const& sp) 1346 { 1347 string s(t.v2, sp); 1348 s.insert(1, 3, '*'); 1349 BOOST_TEST(s == std::string( 1350 t.v2).insert(1, 3, '*')); 1351 }); 1352 1353 // pos out of range 1354 { 1355 string s(t.v1); 1356 BOOST_TEST_THROWS( 1357 (s.insert(s.size() + 2, 1, '*')), 1358 std::out_of_range); 1359 } 1360 1361 // size > max_size 1362 { 1363 string s(t.v1); 1364 BOOST_TEST_THROWS( 1365 (s.insert(1, s.max_size(), 'a')), 1366 std::length_error); 1367 } 1368 } 1369 1370 // insert(size_type, char const*) 1371 { 1372 fail_loop([&](storage_ptr const& sp) 1373 { 1374 string s(t.v1, sp); 1375 s.insert(1, "***"); 1376 BOOST_TEST(s == std::string( 1377 t.v1).insert(1, "***")); 1378 }); 1379 1380 fail_loop([&](storage_ptr const& sp) 1381 { 1382 string s(t.v2, sp); 1383 s.insert(1, "***"); 1384 BOOST_TEST(s == std::string( 1385 t.v2).insert(1, "***")); 1386 }); 1387 1388 // pos out of range 1389 { 1390 string s(t.v1); 1391 BOOST_TEST_THROWS( 1392 (s.insert(s.size() + 2, "*")), 1393 std::out_of_range); 1394 } 1395 } 1396 1397 // insert(size_type, char const*, size_type) 1398 { 1399 fail_loop([&](storage_ptr const& sp) 1400 { 1401 string s(t.v1, sp); 1402 s.insert(1, "*****"); 1403 BOOST_TEST(s == std::string( 1404 t.v1).insert(1, "*****")); 1405 }); 1406 1407 fail_loop([&](storage_ptr const& sp) 1408 { 1409 string s(t.v2, sp); 1410 s.insert(1, "*****"); 1411 BOOST_TEST(s == std::string( 1412 t.v2).insert(1, "*****")); 1413 }); 1414 } 1415 1416 // insert(size_type, string const&) 1417 { 1418 fail_loop([&](storage_ptr const& sp) 1419 { 1420 string s(t.v1, sp); 1421 s.insert(1, string(t.v2)); 1422 BOOST_TEST(s == std::string( 1423 t.v1).insert(1, t.s2)); 1424 }); 1425 1426 fail_loop([&](storage_ptr const& sp) 1427 { 1428 string s(t.v2, sp); 1429 s.insert(1, string(t.v1)); 1430 BOOST_TEST(s == std::string( 1431 t.v2).insert(1, t.s1)); 1432 }); 1433 } 1434 1435 //// KRYSTIAN These tests are superseded by the new string_view overloads 1436 //// insert(size_type, string const&, size_type, size_type) 1437 //{ 1438 // fail_loop([&](storage_ptr const& sp) 1439 // { 1440 // string s(t.v1, sp); 1441 // s.insert(1, string(t.v2), 1, 3); 1442 // BOOST_TEST(s == std::string( 1443 // t.v1).insert(1, t.s2, 1, 3)); 1444 // }); 1445 1446 // fail_loop([&](storage_ptr const& sp) 1447 // { 1448 // string s(t.v2, sp); 1449 // s.insert(1, string(t.v1), 1, 3); 1450 // BOOST_TEST(s == std::string( 1451 // t.v2).insert(1, t.s1, 1, 3)); 1452 // }); 1453 1454 // fail_loop([&](storage_ptr const& sp) 1455 // { 1456 // string s(t.v1, sp); 1457 // s.insert(1, string(t.v2), 1); 1458 // BOOST_TEST(s == std::string( 1459 // t.v1).insert(1, t.s2, 1, std::string::npos)); 1460 // }); 1461 1462 // fail_loop([&](storage_ptr const& sp) 1463 // { 1464 // string s(t.v2, sp); 1465 // s.insert(1, string(t.v1), 1); 1466 // BOOST_TEST(s == std::string( 1467 // t.v2).insert(1, t.s1, 1, std::string::npos)); 1468 // }); 1469 //} 1470 1471 // insert(size_type, char) 1472 { 1473 fail_loop([&](storage_ptr const& sp) 1474 { 1475 string s(t.v1, sp); 1476 BOOST_TEST( 1477 s.insert(2, '*')[2] == '*'); 1478 }); 1479 1480 fail_loop([&](storage_ptr const& sp) 1481 { 1482 string s(t.v2, sp); 1483 BOOST_TEST( 1484 s.insert(2, '*')[2] == '*'); 1485 }); 1486 } 1487 1488 // insert(const_iterator, size_type, char) 1489 { 1490 fail_loop([&](storage_ptr const& sp) 1491 { 1492 string s(t.v1, sp); 1493 BOOST_TEST(string_view( 1494 &(s.insert(2, 3, '*')[2]), 5) == 1495 "***cd"); 1496 }); 1497 1498 fail_loop([&](storage_ptr const& sp) 1499 { 1500 string s(t.v2, sp); 1501 BOOST_TEST(string_view( 1502 &(s.insert(2, 3, '*')[2]), 5) == 1503 "***CD"); 1504 }); 1505 } 1506 1507 // insert(const_iterator, InputIt, InputIt) 1508 { 1509 fail_loop([&](storage_ptr const& sp) 1510 { 1511 string s(t.v1, sp); 1512 s.insert(2, t.s2.begin(), t.s2.end()); 1513 std::string cs(t.s1); 1514 cs.insert(2, &t.s2[0], t.s2.size()); 1515 BOOST_TEST(s == cs); 1516 }); 1517 1518 fail_loop([&](storage_ptr const& sp) 1519 { 1520 string s(t.v2, sp); 1521 s.insert(2, t.s1.begin(), t.s1.end()); 1522 std::string cs(t.s2); 1523 cs.insert(2, &t.s1[0], t.s1.size()); 1524 BOOST_TEST(s == cs); 1525 }); 1526 1527 fail_loop([&](storage_ptr const& sp) 1528 { 1529 string s(t.v1, sp); 1530 s.insert(2, 1531 make_input_iterator(t.s2.begin()), 1532 make_input_iterator(t.s2.end())); 1533 std::string cs(t.s1); 1534 cs.insert(2, &t.s2[0], t.s2.size()); 1535 BOOST_TEST(s == cs); 1536 }); 1537 1538 fail_loop([&](storage_ptr const& sp) 1539 { 1540 string s(t.v2, sp); 1541 s.insert(2, 1542 make_input_iterator(t.s1.begin()), 1543 make_input_iterator(t.s1.end())); 1544 std::string cs(t.s2); 1545 cs.insert(2, &t.s1[0], t.s1.size()); 1546 BOOST_TEST(s == cs); 1547 }); 1548 } 1549 1550 // insert(const_iterator, string_view) 1551 { 1552 fail_loop([&](storage_ptr const& sp) 1553 { 1554 string s(t.v1, sp); 1555 s.insert(2, string_view(t.v2)); 1556 std::string cs(t.v1); 1557 cs.insert(2, t.s2); 1558 BOOST_TEST(s == cs); 1559 }); 1560 1561 fail_loop([&](storage_ptr const& sp) 1562 { 1563 string s(t.v2, sp); 1564 s.insert(2, string_view(t.v1)); 1565 std::string cs(t.v2); 1566 cs.insert(2, t.s1); 1567 BOOST_TEST(s == cs); 1568 }); 1569 } 1570 1571 // insert(const_iterator, string_view) 1572 { 1573 fail_loop([&](storage_ptr const& sp) 1574 { 1575 string s(t.v1, sp); 1576 s.insert(2, string_view(t.v2).substr(2, 3)); 1577 std::string cs(t.v1); 1578 cs.insert(2, t.s2, 2, 3); 1579 BOOST_TEST(s == cs); 1580 }); 1581 1582 fail_loop([&](storage_ptr const& sp) 1583 { 1584 string s(t.v2, sp); 1585 s.insert(2, string_view(t.v1).substr(2, 3)); 1586 std::string cs(t.v2); 1587 cs.insert(2, t.s1, 2, 3); 1588 BOOST_TEST(s == cs); 1589 }); 1590 } 1591 1592 // insert(size_type, char const*) 1593 { 1594 fail_loop([&](storage_ptr const& sp) 1595 { 1596 string s(t.v1, sp); 1597 s.insert(1, "***"); 1598 BOOST_TEST(s == std::string( 1599 t.v1).insert(1, "***")); 1600 }); 1601 1602 fail_loop([&](storage_ptr const& sp) 1603 { 1604 string s(t.v2, sp); 1605 s.insert(1, "***"); 1606 BOOST_TEST(s == std::string( 1607 t.v2).insert(1, "***")); 1608 }); 1609 1610 // pos out of range 1611 { 1612 string s(t.v1); 1613 BOOST_TEST_THROWS( 1614 (s.insert(s.size() + 2, "*")), 1615 std::out_of_range); 1616 } 1617 } 1618 1619 // insert tests for when source is within destination 1620 { 1621 // start before splice point 1622 fail_loop([&](storage_ptr const& sp) 1623 { 1624 string s(t.v1, sp); 1625 s.reserve(s.size() + 10); 1626 s.insert(4, s.subview(0, 3)); 1627 std::string cs(t.v1); 1628 cs.insert(4, cs.substr(0, 3)); 1629 BOOST_TEST(s == cs); 1630 }); 1631 1632 // start after splice point 1633 fail_loop([&](storage_ptr const& sp) 1634 { 1635 string s(t.v1, sp); 1636 s.reserve(s.size() + 10); 1637 s.insert(0, s.subview(3, 3)); 1638 std::string cs(t.v1); 1639 cs.insert(0, cs.substr(3, 3)); 1640 BOOST_TEST(s == cs); 1641 }); 1642 1643 // insert pos bisects the inserted string 1644 fail_loop([&](storage_ptr const& sp) 1645 { 1646 string s(t.v1, sp); 1647 s.reserve(s.size() + 10); 1648 s.insert(2, s.subview(0, 5)); 1649 std::string cs(t.v1); 1650 cs.insert(2, cs.substr(0, 5)); 1651 BOOST_TEST(s == cs); 1652 }); 1653 } 1654 1655 // insert reallocation test 1656 { 1657 fail_loop([&](storage_ptr const& sp) 1658 { 1659 string s(t.v2, sp); 1660 std::string cs(t.v2); 1661 const auto view = t.v2.substr(0, 4); 1662 s.append(s); 1663 cs.append(cs); 1664 s.insert(2, view); 1665 cs.insert(2, view.data(), view.size()); 1666 BOOST_TEST(s == cs); 1667 }); 1668 } 1669 } 1670 1671 void testErase()1672 testErase() 1673 { 1674 test_vectors const t; 1675 1676 // erase(size_type, size_type) 1677 { 1678 { 1679 string s(t.v1); 1680 s.erase(1, 3); 1681 BOOST_TEST(s == 1682 std::string(t.v1).erase(1, 3)); 1683 } 1684 1685 { 1686 string s(t.v2); 1687 s.erase(1, 3); 1688 BOOST_TEST(s == 1689 std::string(t.v2).erase(1, 3)); 1690 } 1691 1692 { 1693 string s(t.v1); 1694 s.erase(3); 1695 BOOST_TEST(s == 1696 std::string(t.v1).erase(3)); 1697 } 1698 1699 { 1700 string s(t.v2); 1701 s.erase(3); 1702 BOOST_TEST(s == 1703 std::string(t.v2).erase(3)); 1704 } 1705 1706 { 1707 string s(t.v1); 1708 s.erase(); 1709 BOOST_TEST(s == 1710 std::string(t.v1).erase()); 1711 } 1712 1713 { 1714 string s(t.v2); 1715 s.erase(); 1716 BOOST_TEST(s == 1717 std::string(t.v2).erase()); 1718 } 1719 1720 { 1721 string s(t.v1); 1722 BOOST_TEST_THROWS( 1723 (s.erase(t.v1.size() + 1, 1)), 1724 std::out_of_range); 1725 } 1726 } 1727 1728 // iterator erase(const_iterator) 1729 { 1730 { 1731 string s(t.v1); 1732 std::string s2(t.v1); 1733 s.erase(s.begin() + 3); 1734 s2.erase(s2.begin() + 3); 1735 BOOST_TEST(s == s2); 1736 } 1737 1738 { 1739 string s(t.v2); 1740 std::string s2(t.v2); 1741 s.erase(s.begin() + 3); 1742 s2.erase(s2.begin() + 3); 1743 BOOST_TEST(s == s2); 1744 } 1745 } 1746 1747 // iterator erase(const_iterator, const_iterator) 1748 { 1749 string s(t.v1); 1750 std::string s2(t.v1); 1751 s.erase(s.begin() + 1, s.begin() + 3); 1752 s2.erase(s2.begin() + 1, s2.begin() + 3); 1753 BOOST_TEST(s == s2); 1754 } 1755 } 1756 1757 void testPushPop()1758 testPushPop() 1759 { 1760 test_vectors const t; 1761 1762 // push_back(char) 1763 { 1764 fail_loop([&](storage_ptr const& sp) 1765 { 1766 string s(sp); 1767 for(auto ch : t.v1) 1768 s.push_back(ch); 1769 BOOST_TEST(s == t.v1); 1770 }); 1771 1772 fail_loop([&](storage_ptr const& sp) 1773 { 1774 string s(sp); 1775 for(auto ch : t.v2) 1776 s.push_back(ch); 1777 BOOST_TEST(s == t.v2); 1778 }); 1779 } 1780 1781 // pop_back(char) 1782 { 1783 { 1784 string s(t.v1); 1785 while(! s.empty()) 1786 s.pop_back(); 1787 BOOST_TEST(s.empty()); 1788 BOOST_TEST(s.capacity() > 0); 1789 } 1790 1791 { 1792 string s(t.v2); 1793 while(! s.empty()) 1794 s.pop_back(); 1795 BOOST_TEST(s.empty()); 1796 BOOST_TEST(s.capacity() > 0); 1797 } 1798 } 1799 } 1800 1801 void testAppend()1802 testAppend() 1803 { 1804 test_vectors const t; 1805 1806 // append(size_type, char) 1807 { 1808 fail_loop([&](storage_ptr const& sp) 1809 { 1810 string s(t.v1, sp); 1811 s.append(t.v2.size(), '*'); 1812 BOOST_TEST(s == t.s1 + 1813 std::string(t.v2.size(), '*')); 1814 }); 1815 1816 fail_loop([&](storage_ptr const& sp) 1817 { 1818 string s(t.v2, sp); 1819 s.append(t.v1.size(), '*'); 1820 BOOST_TEST(s == t.s2 + 1821 std::string(t.v1.size(), '*')); 1822 }); 1823 } 1824 1825 // append(string_view) 1826 { 1827 fail_loop([&](storage_ptr const& sp) 1828 { 1829 string s(t.v1, sp); 1830 s.append(string(t.v2)); 1831 BOOST_TEST(s == t.s1 + t.s2); 1832 }); 1833 1834 fail_loop([&](storage_ptr const& sp) 1835 { 1836 string s(t.v2, sp); 1837 s.append(string(t.v1)); 1838 BOOST_TEST(s == t.s2 + t.s1); 1839 }); 1840 } 1841 1842 // append(string_view) 1843 { 1844 fail_loop([&](storage_ptr const& sp) 1845 { 1846 string s(t.v1, sp); 1847 s.append(string(t.v2).subview(3)); 1848 BOOST_TEST(s == t.s1 + t.s2.substr(3)); 1849 }); 1850 1851 fail_loop([&](storage_ptr const& sp) 1852 { 1853 string s(t.v2, sp); 1854 s.append(string(t.v1).subview(3)); 1855 BOOST_TEST(s == t.s2 + t.s1.substr(3)); 1856 }); 1857 1858 fail_loop([&](storage_ptr const& sp) 1859 { 1860 string s(t.v1, sp); 1861 s.append(string(t.v2).subview(2, 3)); 1862 BOOST_TEST(s == t.s1 + t.s2.substr(2, 3)); 1863 }); 1864 1865 fail_loop([&](storage_ptr const& sp) 1866 { 1867 string s(t.v2, sp); 1868 s.append(string(t.v1).subview(2, 3)); 1869 BOOST_TEST(s == t.s2 + t.s1.substr(2, 3)); 1870 }); 1871 } 1872 1873 // append(char const*) 1874 { 1875 fail_loop([&](storage_ptr const& sp) 1876 { 1877 string s(t.v1, sp); 1878 s.append(t.s2.c_str()); 1879 BOOST_TEST(s == t.s1 + t.s2); 1880 }); 1881 1882 fail_loop([&](storage_ptr const& sp) 1883 { 1884 string s(t.v2, sp); 1885 s.append(t.s1.c_str()); 1886 BOOST_TEST(s == t.s2 + t.s1); 1887 }); 1888 } 1889 1890 // append(InputIt, InputIt) 1891 { 1892 fail_loop([&](storage_ptr const& sp) 1893 { 1894 string s(t.v1, sp); 1895 s.append(t.s2.begin(), t.s2.end()); 1896 BOOST_TEST(s == t.s1 + t.s2); 1897 }); 1898 1899 fail_loop([&](storage_ptr const& sp) 1900 { 1901 string s(t.v2, sp); 1902 s.append(t.s1.begin(), t.s1.end()); 1903 BOOST_TEST(s == t.s2 + t.s1); 1904 }); 1905 1906 // Fails on Visual Studio 2017 C++2a Strict 1907 fail_loop([&](storage_ptr const& sp) 1908 { 1909 string s(t.v1, sp); 1910 s.append( 1911 make_input_iterator(t.s2.begin()), 1912 make_input_iterator(t.s2.end())); 1913 BOOST_TEST(s == t.s1 + t.s2); 1914 }); 1915 1916 fail_loop([&](storage_ptr const& sp) 1917 { 1918 string s(t.v2, sp); 1919 s.append( 1920 make_input_iterator(t.s1.begin()), 1921 make_input_iterator(t.s1.end())); 1922 BOOST_TEST(s == t.s2 + t.s1); 1923 }); 1924 } 1925 1926 // append(string_view) 1927 { 1928 fail_loop([&](storage_ptr const& sp) 1929 { 1930 string s(t.v1, sp); 1931 s.append(t.v2); 1932 BOOST_TEST(s == t.s1 + t.s2); 1933 }); 1934 1935 fail_loop([&](storage_ptr const& sp) 1936 { 1937 string s(t.v2, sp); 1938 s.append(t.v1); 1939 BOOST_TEST(s == t.s2 + t.s1); 1940 }); 1941 } 1942 1943 // append(string_view) 1944 { 1945 fail_loop([&](storage_ptr const& sp) 1946 { 1947 string s(t.v1, sp); 1948 s.append(t.v2.substr(2)); 1949 BOOST_TEST(s == t.s1 + t.s2.substr(2)); 1950 }); 1951 1952 fail_loop([&](storage_ptr const& sp) 1953 { 1954 string s(t.v2, sp); 1955 s.append(t.v1.substr(2)); 1956 BOOST_TEST(s == t.s2 + t.s1.substr(2)); 1957 }); 1958 1959 fail_loop([&](storage_ptr const& sp) 1960 { 1961 string s(t.v1, sp); 1962 s.append(t.v2.substr(2, 3)); 1963 BOOST_TEST(s == t.s1 + t.s2.substr(2, 3)); 1964 }); 1965 1966 fail_loop([&](storage_ptr const& sp) 1967 { 1968 string s(t.v2, sp); 1969 s.append(t.v1.substr(2, 3)); 1970 BOOST_TEST(s == t.s2 + t.s1.substr(2, 3)); 1971 }); 1972 } 1973 } 1974 1975 void testPlusEquals()1976 testPlusEquals() 1977 { 1978 test_vectors const t; 1979 1980 // operator+=(string) 1981 { 1982 fail_loop([&](storage_ptr const& sp) 1983 { 1984 string s(t.v1, sp); 1985 s += string(t.v2); 1986 BOOST_TEST(s == t.s1 + t.s2); 1987 }); 1988 1989 fail_loop([&](storage_ptr const& sp) 1990 { 1991 string s(t.v2, sp); 1992 s += string(t.v1); 1993 BOOST_TEST(s == t.s2 + t.s1); 1994 }); 1995 } 1996 1997 // operator+=(char) 1998 { 1999 fail_loop([&](storage_ptr const& sp) 2000 { 2001 string s(sp); 2002 for(auto ch : t.v1) 2003 s += ch; 2004 BOOST_TEST(s == t.v1); 2005 }); 2006 2007 fail_loop([&](storage_ptr const& sp) 2008 { 2009 string s(sp); 2010 for(auto ch : t.v2) 2011 s += ch; 2012 BOOST_TEST(s == t.v2); 2013 }); 2014 } 2015 2016 // operator+=(char const*) 2017 { 2018 fail_loop([&](storage_ptr const& sp) 2019 { 2020 string s(t.v1, sp); 2021 s += t.s2.c_str(); 2022 BOOST_TEST(s == t.s1 + t.s2); 2023 }); 2024 2025 fail_loop([&](storage_ptr const& sp) 2026 { 2027 string s(t.v2, sp); 2028 s += t.s1.c_str(); 2029 BOOST_TEST(s == t.s2 + t.s1); 2030 }); 2031 } 2032 2033 // operator+=(string_view) 2034 { 2035 fail_loop([&](storage_ptr const& sp) 2036 { 2037 string s(t.v1, sp); 2038 s += t.v2; 2039 BOOST_TEST(s == t.s1 + t.s2); 2040 }); 2041 2042 fail_loop([&](storage_ptr const& sp) 2043 { 2044 string s(t.v2, sp); 2045 s += t.v1; 2046 BOOST_TEST(s == t.s2 + t.s1); 2047 }); 2048 } 2049 } 2050 2051 void testCompare()2052 testCompare() 2053 { 2054 test_vectors const t; 2055 string const v1 = t.v1; 2056 2057 // compare(string) 2058 BOOST_TEST(v1.compare(string("aaaaaaa")) > 0); 2059 BOOST_TEST(v1.compare(string(t.v1)) == 0); 2060 BOOST_TEST(v1.compare(string("bbbbbbb")) < 0); 2061 2062 // compare(char const*) 2063 BOOST_TEST(v1.compare("aaaaaaa") > 0); 2064 BOOST_TEST(v1.compare(t.s1.c_str()) == 0); 2065 BOOST_TEST(v1.compare("bbbbbbb") < 0); 2066 2067 // compare(string_view s) 2068 BOOST_TEST(v1.compare(string_view("aaaaaaa")) > 0); 2069 BOOST_TEST(v1.compare(t.v1) == 0); 2070 BOOST_TEST(v1.compare(string_view("bbbbbbb")) < 0); 2071 } 2072 2073 void testStartEndsWith()2074 testStartEndsWith() 2075 { 2076 test_vectors const t; 2077 string const v1 = t.v1; 2078 string const v2 = t.v2; 2079 2080 // starts_with(string_view) 2081 { 2082 BOOST_TEST(v1.starts_with(string_view("abc"))); 2083 BOOST_TEST(v2.starts_with(string_view("ABC"))); 2084 BOOST_TEST(! v1.starts_with(string_view("xyz"))); 2085 BOOST_TEST(! v2.starts_with(string_view("XYZ"))); 2086 } 2087 2088 // starts_with(char) 2089 { 2090 BOOST_TEST(v1.starts_with('a')); 2091 BOOST_TEST(v2.starts_with('A')); 2092 BOOST_TEST(! v1.starts_with('x')); 2093 BOOST_TEST(! v2.starts_with('X')); 2094 } 2095 2096 // starts_with(char const*) 2097 { 2098 BOOST_TEST(v1.starts_with("abc")); 2099 BOOST_TEST(v2.starts_with("ABC")); 2100 BOOST_TEST(! v1.starts_with("xyz")); 2101 BOOST_TEST(! v2.starts_with("XYZ")); 2102 } 2103 2104 // ends_with(string_view) 2105 { 2106 BOOST_TEST(v1.ends_with(last_of(t.s1,3))); 2107 BOOST_TEST(v2.ends_with(last_of(t.s2,3))); 2108 BOOST_TEST(! v1.ends_with(string_view("abc"))); 2109 BOOST_TEST(! v2.ends_with(string_view("ABC"))); 2110 } 2111 2112 // ends_with(char) 2113 { 2114 BOOST_TEST(v1.ends_with(last_of(t.s1, 1)[0])); 2115 BOOST_TEST(v2.ends_with(last_of(t.s2, 1)[0])); 2116 BOOST_TEST(! v1.ends_with('a')); 2117 BOOST_TEST(! v2.ends_with('A')); 2118 } 2119 2120 // ends_with(char const*) 2121 { 2122 BOOST_TEST(v1.ends_with(last_of(t.s1, 3).data())); 2123 BOOST_TEST(v2.ends_with(last_of(t.s2, 3).data())); 2124 BOOST_TEST(! v1.ends_with("abc")); 2125 BOOST_TEST(! v2.ends_with("ABC")); 2126 } 2127 } 2128 2129 void testReplace()2130 testReplace() 2131 { 2132 test_vectors const t; 2133 2134 // replace(std::size_t, std::size_t, string_view) 2135 { 2136 // pos out of range 2137 fail_loop([&](storage_ptr const& sp) 2138 { 2139 string s(t.v2, sp); 2140 BOOST_TEST_THROWS(s.replace(s.size() + 1, 1, t.v2), 2141 std::out_of_range); 2142 }); 2143 2144 // outside, shrink 2145 fail_loop([&](storage_ptr const& sp) 2146 { 2147 std::string s1(t.v2.data(), t.v2.size()); 2148 string s2(t.v2, sp); 2149 BOOST_TEST(s2.replace(0, 4, t.v2.substr(4, 2)) == 2150 s1.replace(0, 4, t.v2.data() + 4, 2)); 2151 }); 2152 2153 // outside, grow 2154 fail_loop([&](storage_ptr const& sp) 2155 { 2156 std::string s1(t.v2.data(), t.v2.size()); 2157 string s2(t.v2, sp); 2158 BOOST_TEST(s2.replace(0, 1, t.v2.substr(0)) == 2159 s1.replace(0, 1, t.v2.data(), t.v2.size())); 2160 }); 2161 2162 // outside, grow, reallocate 2163 fail_loop([&](storage_ptr const& sp) 2164 { 2165 std::string s1(t.v2.data(), t.v2.size()); 2166 string s2(t.v2, sp); 2167 s1.append(s1); 2168 s2.append(s2); 2169 BOOST_TEST(s2.replace(0, 1, t.v2.substr(0)) == 2170 s1.replace(0, 1, t.v2.data(), t.v2.size())); 2171 }); 2172 2173 // outside, same 2174 fail_loop([&](storage_ptr const& sp) 2175 { 2176 std::string s1(t.v2.data(), t.v2.size()); 2177 string s2(t.v2, sp); 2178 BOOST_TEST(s2.replace(0, 2, t.v2.substr(0, 2)) == 2179 s1.replace(0, 2, t.v2.data(), 2)); 2180 }); 2181 2182 // replace tests for full coverage 2183 2184 // inside, no effect 2185 fail_loop([&](storage_ptr const& sp) 2186 { 2187 std::string s1(t.v2.data(), t.v2.size()); 2188 string s2(t.v2, sp); 2189 BOOST_TEST(s2.replace(0, 4, s2.subview(0, 4)) == 2190 s1.replace(0, 4, s1.data() + 0, 4)); 2191 }); 2192 2193 // inside, shrink, split 2194 fail_loop([&](storage_ptr const& sp) 2195 { 2196 std::string s1(t.v2.data(), t.v2.size()); 2197 string s2(t.v2, sp); 2198 BOOST_TEST(s2.replace(1, 4, s2.subview(4, 2)) == 2199 s1.replace(1, 4, s1.data() + 4, 2)); 2200 }); 2201 2202 // inside, grow no reallocate, split 2203 fail_loop([&](storage_ptr const& sp) 2204 { 2205 std::string s1(t.v2.data(), t.v2.size()); 2206 string s2(t.v2, sp); 2207 BOOST_TEST(s2.replace(1, 1, s2.subview(0)) == 2208 s1.replace(1, 1, s1.data(), s1.size())); 2209 }); 2210 2211 // inside, reallocate, split 2212 fail_loop([&](storage_ptr const& sp) 2213 { 2214 std::string s1(t.v2.data(), t.v2.size()); 2215 string s2(t.v2, sp); 2216 s1.append(s1); 2217 s2.append(s2); 2218 BOOST_TEST(s2.replace(1, 1, s2.subview(0)) == 2219 s1.replace(1, 1, s1.data(), s1.size())); 2220 }); 2221 2222 // inside, same, split 2223 fail_loop([&](storage_ptr const& sp) 2224 { 2225 std::string s1(t.v2.data(), t.v2.size()); 2226 string s2(t.v2, sp); 2227 BOOST_TEST(s2.replace(1, 2, s2.subview(0, 2)) == 2228 s1.replace(1, 2, s1.data(), 2)); 2229 }); 2230 } 2231 2232 // replace(const_iterator, const_iterator, string_view) 2233 { 2234 // outside, shrink 2235 fail_loop([&](storage_ptr const& sp) 2236 { 2237 std::string s1(t.v2.data(), t.v2.size()); 2238 string s2(t.v2, sp); 2239 BOOST_TEST( 2240 s2.replace( 2241 s2.begin(), 2242 s2.begin() + 4, 2243 t.v2.substr(4, 2)) == 2244 s1.replace(0, 2245 4, t.v2.data() + 4, 2246 2)); 2247 }); 2248 2249 // outside, grow 2250 fail_loop([&](storage_ptr const& sp) 2251 { 2252 std::string s1(t.v2.data(), t.v2.size()); 2253 string s2(t.v2, sp); 2254 BOOST_TEST( 2255 s2.replace( 2256 s2.begin(), 2257 s2.begin() + 1, 2258 t.v2.substr(0)) == 2259 s1.replace(0, 2260 1, t.v2.data(), 2261 t.v2.size())); 2262 }); 2263 2264 // outside, same 2265 fail_loop([&](storage_ptr const& sp) 2266 { 2267 std::string s1(t.v2.data(), t.v2.size()); 2268 string s2(t.v2, sp); 2269 BOOST_TEST( 2270 s2.replace( 2271 s2.begin(), 2272 s2.begin() + 2, 2273 t.v2.substr(0, 2)) == 2274 s1.replace( 2275 0, 2, 2276 t.v2.data(), 2277 2)); 2278 }); 2279 2280 // inside, shrink 2281 fail_loop([&](storage_ptr const& sp) 2282 { 2283 std::string s1(t.v2.data(), t.v2.size()); 2284 string s2(t.v2, sp); 2285 BOOST_TEST( 2286 s2.replace( 2287 s2.begin() + 1, 2288 s2.begin() + 5, 2289 s2.subview(4, 2)) == 2290 s1.replace( 2291 1, 4, 2292 s1.data() + 4, 2293 2)); 2294 }); 2295 2296 // inside, grow 2297 fail_loop([&](storage_ptr const& sp) 2298 { 2299 std::string s1(t.v2.data(), t.v2.size()); 2300 string s2(t.v2, sp); 2301 BOOST_TEST( 2302 s2.replace( 2303 s2.begin() + 1, 2304 s2.begin() + 2, 2305 s2.subview(0)) == 2306 s1.replace( 2307 1, 1, 2308 s1.data(), 2309 s1.size())); 2310 }); 2311 2312 // inside, same 2313 fail_loop([&](storage_ptr const& sp) 2314 { 2315 std::string s1(t.v2.data(), t.v2.size()); 2316 string s2(t.v2, sp); 2317 BOOST_TEST( 2318 s2.replace( 2319 s2.begin() + 1, 2320 s2.begin() + 3, 2321 s2.subview(0, 2)) == 2322 s1.replace( 2323 1, 2, 2324 s1.data(), 2325 2)); 2326 }); 2327 } 2328 2329 // replace(std::size_t, std::size_t, std::size_t, char) 2330 { 2331 // grow, no realloc 2332 fail_loop([&](storage_ptr const& sp) 2333 { 2334 std::string s1(t.v2.data(), t.v2.size()); 2335 string s2(t.v2, sp); 2336 BOOST_TEST(s2.replace(0, 4, 10, 'a') == 2337 s1.replace(0, 4, 10, 'a')); 2338 }); 2339 2340 // grow, realloc 2341 fail_loop([&](storage_ptr const& sp) 2342 { 2343 std::string s1(t.v2.data(), t.v2.size()); 2344 string s2(t.v2, sp); 2345 const auto grow = (std::max)(s1.capacity(), s2.capacity()); 2346 BOOST_TEST(s2.replace(0, 4, grow, 'a') == 2347 s1.replace(0, 4, grow, 'a')); 2348 }); 2349 2350 // no change in size 2351 fail_loop([&](storage_ptr const& sp) 2352 { 2353 std::string s1(t.v2.data(), t.v2.size()); 2354 string s2(t.v2, sp); 2355 BOOST_TEST(s2.replace(0, 1, 1, 'a') == 2356 s1.replace(0, 1, 1, 'a')); 2357 }); 2358 2359 // pos out of range 2360 fail_loop([&](storage_ptr const& sp) 2361 { 2362 string s(t.v2, sp); 2363 BOOST_TEST_THROWS(s.replace(s.size() + 1, 1, 1, 'a'), 2364 std::out_of_range); 2365 }); 2366 } 2367 2368 // replace(const_iterator, const_iterator, std::size_t, char) 2369 { 2370 fail_loop([&](storage_ptr const& sp) 2371 { 2372 std::string s1(t.v2.data(), t.v2.size()); 2373 string s2(t.v2, sp); 2374 BOOST_TEST( 2375 s2.replace(s2.begin(), s2.begin() + 4, 10, 'a') == 2376 s1.replace(0, 4, 10, 'a')); 2377 }); 2378 } 2379 } 2380 2381 void testSubStr()2382 testSubStr() 2383 { 2384 test_vectors const t; 2385 string const s1 = t.v1; 2386 string const s2 = t.v2; 2387 2388 // subview(size_type, size_type) 2389 BOOST_TEST(s1.subview() == t.v1); 2390 BOOST_TEST(s1.subview(1) == t.v1.substr(1)); 2391 BOOST_TEST(s1.subview(1, 3) == t.v1.substr(1, 3)); 2392 BOOST_TEST(s2.subview() == t.v2); 2393 BOOST_TEST(s2.subview(1) == t.v2.substr(1)); 2394 BOOST_TEST(s2.subview(1, 3) == t.v2.substr(1, 3)); 2395 } 2396 2397 void testCopy()2398 testCopy() 2399 { 2400 test_vectors const t; 2401 2402 // copy(char*, count, pos) 2403 { 2404 { 2405 string s(t.v1); 2406 std::string d; 2407 d.resize(s.size()); 2408 s.copy(&d[0], d.size(), 0); 2409 BOOST_TEST(d == t.v1); 2410 } 2411 2412 { 2413 string s(t.v1); 2414 std::string d; 2415 d.resize(s.size()); 2416 s.copy(&d[0], d.size()); 2417 BOOST_TEST(d == t.v1); 2418 } 2419 } 2420 } 2421 2422 void testResize()2423 testResize() 2424 { 2425 test_vectors const t; 2426 2427 // resize(size_type) 2428 { 2429 fail_loop([&](storage_ptr const& sp) 2430 { 2431 string s(sp); 2432 s.resize(t.v1.size()); 2433 BOOST_TEST(s.size() == t.v1.size()); 2434 BOOST_TEST(s == string(t.v1.size(), '\0')); 2435 }); 2436 2437 fail_loop([&](storage_ptr const& sp) 2438 { 2439 string s(sp); 2440 s.resize(t.v2.size()); 2441 BOOST_TEST(s.size() == t.v2.size()); 2442 BOOST_TEST(s == string(t.v2.size(), '\0')); 2443 }); 2444 2445 fail_loop([&](storage_ptr const& sp) 2446 { 2447 string s(sp); 2448 s.resize(t.v1.size()); 2449 s.resize(t.v2.size()); 2450 BOOST_TEST(s == string(t.v2.size(), '\0')); 2451 s.resize(t.v1.size()); 2452 BOOST_TEST(s == string(t.v1.size(), '\0')); 2453 }); 2454 } 2455 2456 // resize(size_type, char) 2457 { 2458 fail_loop([&](storage_ptr const& sp) 2459 { 2460 string s(sp); 2461 s.resize(t.v1.size(), '*'); 2462 BOOST_TEST(s.size() == t.v1.size()); 2463 BOOST_TEST(s == string(t.v1.size(), '*')); 2464 }); 2465 2466 fail_loop([&](storage_ptr const& sp) 2467 { 2468 string s(sp); 2469 s.resize(t.v2.size(), '*'); 2470 BOOST_TEST(s.size() == t.v2.size()); 2471 BOOST_TEST(s == string(t.v2.size(), '*')); 2472 }); 2473 2474 fail_loop([&](storage_ptr const& sp) 2475 { 2476 string s(sp); 2477 s.resize(t.v1.size(), '*'); 2478 s.resize(t.v2.size(), '*'); 2479 BOOST_TEST(s == string(t.v2.size(), '*')); 2480 s.resize(t.v1.size()); 2481 BOOST_TEST(s == string(t.v1.size(), '*')); 2482 }); 2483 } 2484 } 2485 2486 void testSwap()2487 testSwap() 2488 { 2489 test_vectors const t; 2490 2491 // swap 2492 { 2493 fail_loop([&](storage_ptr const& sp) 2494 { 2495 string s1(t.v1, sp); 2496 string s2(t.v2, sp); 2497 s1.swap(s2); 2498 BOOST_TEST(s1 == t.v2); 2499 BOOST_TEST(s2 == t.v1); 2500 }); 2501 2502 fail_loop([&](storage_ptr const& sp) 2503 { 2504 string s1(t.v1, sp); 2505 string s2(t.v2, sp); 2506 swap(s1, s2); 2507 BOOST_TEST(s1 == t.v2); 2508 BOOST_TEST(s2 == t.v1); 2509 }); 2510 2511 fail_loop([&](storage_ptr const& sp) 2512 { 2513 string s1(t.v1); 2514 string s2(t.v2, sp); 2515 s1.swap(s2); 2516 BOOST_TEST(s1 == t.v2); 2517 BOOST_TEST(s2 == t.v1); 2518 }); 2519 } 2520 } 2521 2522 void testFind()2523 testFind() 2524 { 2525 test_vectors const t; 2526 string const s1 = t.v1; 2527 2528 // find(string_view, size_type) 2529 BOOST_TEST(s1.find("bcd") == 1); 2530 BOOST_TEST(s1.find("cde") == 2); 2531 2532 BOOST_TEST(s1.find("bcd", 0) == 1); 2533 BOOST_TEST(s1.find("cde", 1) == 2); 2534 BOOST_TEST(s1.find("efg", 5) == string::npos); 2535 2536 // find(char, size_type) 2537 BOOST_TEST(s1.find('b') == 1); 2538 BOOST_TEST(s1.find('c', 1) == 2); 2539 BOOST_TEST(s1.find('e', 5) == string::npos); 2540 } 2541 2542 void testRfind()2543 testRfind() 2544 { 2545 test_vectors const t; 2546 string const s1 = t.v1; 2547 2548 // rfind(string_view, size_type) 2549 BOOST_TEST(s1.rfind("bcd") == 1); 2550 BOOST_TEST(s1.rfind("cde") == 2); 2551 2552 BOOST_TEST(s1.rfind("bcd", 1) == 1); 2553 BOOST_TEST(s1.rfind("cde", 2) == 2); 2554 BOOST_TEST(s1.rfind("efg", 3) == string::npos); 2555 2556 // rfind(char, size_type) 2557 BOOST_TEST(s1.rfind('b') == 1); 2558 BOOST_TEST(s1.rfind('c', 2) == 2); 2559 BOOST_TEST(s1.rfind('e', 3) == string::npos); 2560 } 2561 2562 void testFindFirstOf()2563 testFindFirstOf() 2564 { 2565 test_vectors const t; 2566 string const s1 = t.v1; 2567 2568 // find_first_of(string_view, size_type) 2569 BOOST_TEST(s1.find_first_of("bcd") == 1); 2570 BOOST_TEST(s1.find_first_of("cde") == 2); 2571 2572 BOOST_TEST(s1.find_first_of("bcd", 0) == 1); 2573 BOOST_TEST(s1.find_first_of("cde", 1) == 2); 2574 BOOST_TEST(s1.find_first_of("efg", 7) == string::npos); 2575 } 2576 2577 void testFindFirstNotOf()2578 testFindFirstNotOf() 2579 { 2580 test_vectors const t; 2581 string const s1 = t.v1; 2582 2583 // find_first_not_of(string_view, size_type) 2584 BOOST_TEST(s1.find_first_not_of("abc") == 3); 2585 BOOST_TEST(s1.find_first_not_of("cde") == 0); 2586 2587 BOOST_TEST(s1.find_first_not_of("bcd", 0) == 0); 2588 BOOST_TEST(s1.find_first_not_of("cde", 2) == 5); 2589 2590 // find_first_not_of(char, size_type) 2591 BOOST_TEST(s1.find_first_not_of('b') == 0); 2592 BOOST_TEST(s1.find_first_not_of('a', 0) == 1); 2593 BOOST_TEST(s1.find_first_not_of('e', 4) == 5); 2594 } 2595 2596 void testFindLastOf()2597 testFindLastOf() 2598 { 2599 test_vectors const t; 2600 string const s1 = t.v1; 2601 2602 // find_last_of(string_view, size_type) 2603 BOOST_TEST(s1.find_last_of("bcd") == 3); 2604 BOOST_TEST(s1.find_last_of("cde") == 4); 2605 2606 BOOST_TEST(s1.find_last_of("bcd", 3) == 3); 2607 BOOST_TEST(s1.find_last_of("cde", 5) == 4); 2608 BOOST_TEST(s1.find_last_of("efg", 3) == string::npos); 2609 } 2610 2611 void testFindLastNotOf()2612 testFindLastNotOf() 2613 { 2614 test_vectors const t; 2615 string const s1 = t.v1; 2616 2617 // find_last_not_of(string_view, size_type) 2618 BOOST_TEST(s1.find_last_not_of("abc", 3) == 3); 2619 BOOST_TEST(s1.find_last_not_of("bcd", 3) == 0); 2620 2621 BOOST_TEST(s1.find_last_not_of("efg", 4) == 3); 2622 BOOST_TEST(s1.find_last_not_of("abc", 2) == string::npos); 2623 2624 // find_first_not_of(char, size_type) 2625 BOOST_TEST(s1.find_last_not_of('a', 3) == 3); 2626 BOOST_TEST(s1.find_last_not_of('e', 4) == 3); 2627 BOOST_TEST(s1.find_last_not_of('a', 0) == string::npos); 2628 } 2629 2630 void testNonMembers()2631 testNonMembers() 2632 { 2633 test_vectors const t; 2634 string const s1(t.v1); 2635 string const s2(t.v2); 2636 auto const v1(t.v1); 2637 auto const v2(t.v2); 2638 auto const c1 = t.s1.c_str(); 2639 auto const c2 = t.s2.c_str(); 2640 2641 BOOST_TEST(! operator< (s1, s2)); 2642 BOOST_TEST(! operator< (s1, v2)); 2643 BOOST_TEST(! operator< (s1, c2)); 2644 BOOST_TEST(! operator<=(s1, s2)); 2645 BOOST_TEST(! operator<=(s1, v2)); 2646 BOOST_TEST(! operator<=(s1, c2)); 2647 BOOST_TEST(! operator==(s1, s2)); 2648 BOOST_TEST(! operator==(s1, v2)); 2649 BOOST_TEST(! operator==(s1, c2)); 2650 BOOST_TEST( operator!=(s1, s2)); 2651 BOOST_TEST( operator!=(s1, v2)); 2652 BOOST_TEST( operator!=(s1, c2)); 2653 BOOST_TEST( operator>=(s1, s2)); 2654 BOOST_TEST( operator>=(s1, v2)); 2655 BOOST_TEST( operator>=(s1, c2)); 2656 BOOST_TEST( operator> (s1, s2)); 2657 BOOST_TEST( operator> (s1, v2)); 2658 BOOST_TEST( operator> (s1, c2)); 2659 2660 BOOST_TEST( operator< (s2, s1)); 2661 BOOST_TEST( operator< (s2, v1)); 2662 BOOST_TEST( operator< (s2, c1)); 2663 BOOST_TEST( operator<=(s2, s1)); 2664 BOOST_TEST( operator<=(s2, v1)); 2665 BOOST_TEST( operator<=(s2, c1)); 2666 BOOST_TEST( operator!=(s2, s1)); 2667 BOOST_TEST( operator!=(s2, v1)); 2668 BOOST_TEST( operator!=(s2, c1)); 2669 BOOST_TEST(! operator==(s2, s1)); 2670 BOOST_TEST(! operator==(s2, v1)); 2671 BOOST_TEST(! operator==(s2, c1)); 2672 BOOST_TEST(! operator>=(s2, s1)); 2673 BOOST_TEST(! operator>=(s2, v1)); 2674 BOOST_TEST(! operator>=(s2, c1)); 2675 BOOST_TEST(! operator> (s2, s1)); 2676 BOOST_TEST(! operator> (s2, v1)); 2677 BOOST_TEST(! operator> (s2, c1)); 2678 2679 BOOST_TEST( operator< (s2, s1)); 2680 BOOST_TEST( operator< (v2, s1)); 2681 BOOST_TEST( operator< (c2, s1)); 2682 BOOST_TEST( operator<=(s2, s1)); 2683 BOOST_TEST( operator<=(v2, s1)); 2684 BOOST_TEST( operator<=(c2, s1)); 2685 BOOST_TEST( operator!=(s2, s1)); 2686 BOOST_TEST( operator!=(v2, s1)); 2687 BOOST_TEST( operator!=(c2, s1)); 2688 BOOST_TEST(! operator==(s2, s1)); 2689 BOOST_TEST(! operator==(v2, s1)); 2690 BOOST_TEST(! operator==(c2, s1)); 2691 BOOST_TEST(! operator>=(s2, s1)); 2692 BOOST_TEST(! operator>=(v2, s1)); 2693 BOOST_TEST(! operator>=(c2, s1)); 2694 BOOST_TEST(! operator> (s2, s1)); 2695 BOOST_TEST(! operator> (v2, s1)); 2696 BOOST_TEST(! operator> (c2, s1)); 2697 2698 BOOST_TEST(! operator< (s1, s2)); 2699 BOOST_TEST(! operator< (v1, s2)); 2700 BOOST_TEST(! operator< (c1, s2)); 2701 BOOST_TEST(! operator<=(s1, s2)); 2702 BOOST_TEST(! operator<=(v1, s2)); 2703 BOOST_TEST(! operator<=(c1, s2)); 2704 BOOST_TEST(! operator==(s1, s2)); 2705 BOOST_TEST(! operator==(v1, s2)); 2706 BOOST_TEST(! operator==(c1, s2)); 2707 BOOST_TEST( operator!=(s1, s2)); 2708 BOOST_TEST( operator!=(v1, s2)); 2709 BOOST_TEST( operator!=(c1, s2)); 2710 BOOST_TEST( operator>=(s1, s2)); 2711 BOOST_TEST( operator>=(v1, s2)); 2712 BOOST_TEST( operator>=(c1, s2)); 2713 BOOST_TEST( operator> (s1, s2)); 2714 BOOST_TEST( operator> (v1, s2)); 2715 BOOST_TEST( operator> (c1, s2)); 2716 } 2717 2718 void testHash()2719 testHash() 2720 { 2721 // libstdc++ 4.8 bug 2722 #if !defined(__GNUC__) || (__GNUC__ > 4 || \ 2723 (__GNUC__ == 4 && __GNUC_MINOR__ > 8)) 2724 { 2725 std::unordered_set<string> us; 2726 us.emplace("first"); 2727 us.emplace("second"); 2728 } 2729 { 2730 std::unordered_set<string>( 2731 0, 2732 std::hash<string>(32)); 2733 } 2734 #endif 2735 { 2736 std::hash<string> h1(32); 2737 std::hash<string> h2(h1); 2738 std::hash<string> h3(59); 2739 h1 = h3; 2740 h2 = h3; 2741 (void)h2; 2742 } 2743 } 2744 2745 void run()2746 run() 2747 { 2748 testConstruction(); 2749 testAssignment(); 2750 testAssign(); 2751 testElementAccess(); 2752 testIterators(); 2753 testCapacity(); 2754 2755 testClear(); 2756 testInsert(); 2757 testErase(); 2758 testPushPop(); 2759 testAppend(); 2760 testPlusEquals(); 2761 testCompare(); 2762 testStartEndsWith(); 2763 testReplace(); 2764 testSubStr(); 2765 testCopy(); 2766 testResize(); 2767 testSwap(); 2768 2769 testFind(); 2770 testRfind(); 2771 testFindFirstOf(); 2772 testFindFirstNotOf(); 2773 testFindLastOf(); 2774 testFindLastNotOf(); 2775 2776 testNonMembers(); 2777 2778 testHash(); 2779 } 2780 }; 2781 2782 TEST_SUITE(string_test, "boost.json.string"); 2783 2784 BOOST_JSON_NS_END 2785