]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/json/test/string.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / json / test / string.cpp
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
55 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([&]
64 {
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
81 last_of(
82 string_view s,
83 std::size_t n)
84 {
85 return s.substr(s.size() - n);
86 }
87
88 void
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
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
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
978 testConversion()
979 {
980 test_vectors const t;
981
982 string s(t.s1);
983 auto const& cs(s);
984
985 char const* chars = cs.c_str();
986 BOOST_TEST(chars == t.s1);
987 json::string_view sv = cs;
988 BOOST_TEST(sv == t.s1);
989 #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
990 std::string_view std_sv = cs;
991 BOOST_TEST(std_sv == t.s1);
992 #endif
993
994 s = t.s2;
995
996 chars = cs.c_str();
997 BOOST_TEST(chars == t.s2);
998 sv = cs;
999 BOOST_TEST(sv == t.s2);
1000 #if ! defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
1001 std_sv = cs;
1002 BOOST_TEST(std_sv == t.s2);
1003 #endif
1004 }
1005
1006 void
1007 testElementAccess()
1008 {
1009 test_vectors const t;
1010
1011 string s1(t.v1);
1012 string s2(t.v2);
1013 auto const& cs1(s1);
1014 auto const& cs2(s2);
1015
1016 // at(size_type)
1017 {
1018 BOOST_TEST(s1.at(1) == 'b');
1019 s1.at(1) = '*';
1020 BOOST_TEST(s1.at(1) == '*');
1021 s1.at(1) = 'b';
1022 BOOST_TEST(s1.at(1) == 'b');
1023
1024 BOOST_TEST(s2.at(1) == 'B');
1025 s2.at(1) = '*';
1026 BOOST_TEST(s2.at(1) == '*');
1027 s2.at(1) = 'B';
1028 BOOST_TEST(s2.at(1) == 'B');
1029
1030 BOOST_TEST_THROWS(s1.at(s2.size()),
1031 std::out_of_range);
1032 }
1033
1034 // at(size_type) const
1035 {
1036 BOOST_TEST(cs1.at(1) == 'b');
1037 BOOST_TEST(cs2.at(1) == 'B');
1038
1039 BOOST_TEST_THROWS(cs1.at(cs2.size()),
1040 std::out_of_range);
1041 }
1042
1043 // operator[&](size_type)
1044 {
1045 BOOST_TEST(s1[1] == 'b');
1046 s1[1] = '*';
1047 BOOST_TEST(s1[1] == '*');
1048 s1[1] = 'b';
1049 BOOST_TEST(s1[1] == 'b');
1050
1051 BOOST_TEST(s2[1] == 'B');
1052 s2[1] = '*';
1053 BOOST_TEST(s2[1] == '*');
1054 s2[1] = 'B';
1055 BOOST_TEST(s2[1] == 'B');
1056 }
1057
1058 // operator[&](size_type) const
1059 {
1060 BOOST_TEST(cs1[1] == 'b');
1061 BOOST_TEST(cs2[1] == 'B');
1062 }
1063
1064 // front()
1065 {
1066 BOOST_TEST(s1.front() == 'a');
1067 s1.front() = '*';
1068 BOOST_TEST(s1.front() == '*');
1069 s1.front() = 'a';
1070 BOOST_TEST(s1.front() == 'a');
1071
1072 BOOST_TEST(s2.front() == 'A');
1073 s2.front() = '*';
1074 BOOST_TEST(s2.front() == '*');
1075 s2.front() = 'A';
1076 BOOST_TEST(s2.front() == 'A');
1077 }
1078
1079 // front() const
1080 {
1081 BOOST_TEST(cs1.front() == 'a');
1082 BOOST_TEST(cs2.front() == 'A');
1083 }
1084
1085 // back()
1086 {
1087 auto const ch1 = s1.at(s1.size()-1);
1088 auto const ch2 = s2.at(s2.size()-1);
1089
1090 BOOST_TEST(s1.back() == ch1);
1091 s1.back() = '*';
1092 BOOST_TEST(s1.back() == '*');
1093 s1.back() = ch1;
1094 BOOST_TEST(s1.back() == ch1);
1095
1096 BOOST_TEST(s2.back() == ch2);
1097 s2.back() = '*';
1098 BOOST_TEST(s2.back() == '*');
1099 s2.back() = ch2;
1100 BOOST_TEST(s2.back() == ch2);
1101 }
1102
1103 // back() const
1104 {
1105 auto const ch1 = s1.at(s1.size()-1);
1106 auto const ch2 = s2.at(s2.size()-1);
1107
1108 BOOST_TEST(cs1.back() == ch1);
1109 BOOST_TEST(cs2.back() == ch2);
1110 }
1111
1112 // data()
1113 {
1114 BOOST_TEST(
1115 string_view(s1.data()) == t.v1);
1116 BOOST_TEST(
1117 string_view(s2.data()) == t.v2);
1118 }
1119 // data() const
1120 {
1121 BOOST_TEST(
1122 string_view(cs1.data()) == t.v1);
1123 BOOST_TEST(
1124 string_view(cs2.data()) == t.v2);
1125 }
1126
1127 // c_str()
1128 {
1129 BOOST_TEST(
1130 string_view(cs1.c_str()) == t.v1);
1131 BOOST_TEST(
1132 string_view(cs2.c_str()) == t.v2);
1133 }
1134
1135 // operator string_view()
1136 {
1137 BOOST_TEST(
1138 string_view(cs1) == t.v1);
1139 BOOST_TEST(
1140 string_view(cs2) == t.v2);
1141 }
1142 }
1143
1144 void
1145 testIterators()
1146 {
1147 string s = "abc";
1148 auto const& ac(s);
1149
1150 {
1151 auto it = s.begin();
1152 BOOST_TEST(*it == 'a'); ++it;
1153 BOOST_TEST(*it == 'b'); it++;
1154 BOOST_TEST(*it == 'c'); ++it;
1155 BOOST_TEST(it == s.end());
1156 }
1157 {
1158 auto it = s.cbegin();
1159 BOOST_TEST(*it == 'a'); ++it;
1160 BOOST_TEST(*it == 'b'); it++;
1161 BOOST_TEST(*it == 'c'); ++it;
1162 BOOST_TEST(it == s.cend());
1163 }
1164 {
1165 auto it = ac.begin();
1166 BOOST_TEST(*it == 'a'); ++it;
1167 BOOST_TEST(*it == 'b'); it++;
1168 BOOST_TEST(*it == 'c'); ++it;
1169 BOOST_TEST(it == ac.end());
1170 }
1171 {
1172 auto it = s.end();
1173 --it; BOOST_TEST(*it == 'c');
1174 it--; BOOST_TEST(*it == 'b');
1175 --it; BOOST_TEST(*it == 'a');
1176 BOOST_TEST(it == s.begin());
1177 }
1178 {
1179 auto it = s.cend();
1180 --it; BOOST_TEST(*it == 'c');
1181 it--; BOOST_TEST(*it == 'b');
1182 --it; BOOST_TEST(*it == 'a');
1183 BOOST_TEST(it == s.cbegin());
1184 }
1185 {
1186 auto it = ac.end();
1187 --it; BOOST_TEST(*it == 'c');
1188 it--; BOOST_TEST(*it == 'b');
1189 --it; BOOST_TEST(*it == 'a');
1190 BOOST_TEST(it == ac.begin());
1191 }
1192
1193 {
1194 auto it = s.rbegin();
1195 BOOST_TEST(*it == 'c'); ++it;
1196 BOOST_TEST(*it == 'b'); it++;
1197 BOOST_TEST(*it == 'a'); ++it;
1198 BOOST_TEST(it == s.rend());
1199 }
1200 {
1201 auto it = s.crbegin();
1202 BOOST_TEST(*it == 'c'); ++it;
1203 BOOST_TEST(*it == 'b'); it++;
1204 BOOST_TEST(*it == 'a'); ++it;
1205 BOOST_TEST(it == s.crend());
1206 }
1207 {
1208 auto it = ac.rbegin();
1209 BOOST_TEST(*it == 'c'); ++it;
1210 BOOST_TEST(*it == 'b'); it++;
1211 BOOST_TEST(*it == 'a'); ++it;
1212 BOOST_TEST(it == ac.rend());
1213 }
1214 {
1215 auto it = s.rend();
1216 --it; BOOST_TEST(*it == 'a');
1217 it--; BOOST_TEST(*it == 'b');
1218 --it; BOOST_TEST(*it == 'c');
1219 BOOST_TEST(it == s.rbegin());
1220 }
1221 {
1222 auto it = s.crend();
1223 --it; BOOST_TEST(*it == 'a');
1224 it--; BOOST_TEST(*it == 'b');
1225 --it; BOOST_TEST(*it == 'c');
1226 BOOST_TEST(it == s.crbegin());
1227 }
1228 {
1229 auto it = ac.rend();
1230 --it; BOOST_TEST(*it == 'a');
1231 it--; BOOST_TEST(*it == 'b');
1232 --it; BOOST_TEST(*it == 'c');
1233 BOOST_TEST(it == ac.rbegin());
1234 }
1235
1236 {
1237 string s2;
1238 string const& cs2(s2);
1239 BOOST_TEST(std::distance(
1240 s2.begin(), s2.end()) == 0);
1241 BOOST_TEST(std::distance(
1242 cs2.begin(), cs2.end()) == 0);
1243 BOOST_TEST(std::distance(
1244 s2.rbegin(), s2.rend()) == 0);
1245 BOOST_TEST(std::distance(
1246 cs2.rbegin(), cs2.rend()) == 0);
1247 }
1248 }
1249
1250 void
1251 testCapacity()
1252 {
1253 test_vectors const t;
1254
1255 // empty()
1256 {
1257 {
1258 string s;
1259 BOOST_TEST(s.empty());
1260 }
1261 {
1262 string s = "abc";
1263 BOOST_TEST(! s.empty());
1264 }
1265 }
1266
1267 // size()
1268 // max_size()
1269 {
1270 string s = "abc";
1271 BOOST_TEST(s.size() == 3);
1272 BOOST_TEST(s.max_size() < string::npos);
1273 }
1274
1275 // reserve(size_type)
1276 {
1277 fail_loop([&](storage_ptr const& sp)
1278 {
1279 string s(sp);
1280 s.append(t.v1);
1281 s.append(t.v2);
1282
1283 s.reserve(0);
1284 BOOST_TEST(s.size() ==
1285 t.v1.size() + t.v2.size());
1286
1287 s.reserve(t.v1.size() + t.v2.size());
1288 BOOST_TEST(s.size() ==
1289 t.v1.size() + t.v2.size());
1290
1291 s.reserve(s.size() * 2);
1292 BOOST_TEST(s.capacity() >
1293 t.v1.size() + t.v2.size());
1294
1295 s.resize(t.v1.size());
1296 s.reserve(t.v1.size());
1297 BOOST_TEST(s == t.v1);
1298 });
1299 }
1300
1301 // capacity()
1302 {
1303 // implied
1304 }
1305
1306 // shrink_to_fit()
1307 fail_loop([&](storage_ptr const& sp)
1308 {
1309 string s(sp);
1310 string::size_type cap;
1311
1312 cap = s.capacity();
1313 s.shrink_to_fit();
1314 BOOST_TEST(s.capacity() == cap);
1315
1316 s.reserve(s.capacity() + 1);
1317 s.shrink_to_fit();
1318 BOOST_TEST(s.capacity() == cap);
1319
1320 s.resize(cap * 3, '*');
1321 cap = s.capacity();
1322 s.resize(cap - 1);
1323 s.shrink_to_fit();
1324 BOOST_TEST(s.capacity() == cap);
1325
1326 s.resize(cap / 2);
1327 BOOST_TEST(s.capacity() == cap);
1328
1329 s.shrink_to_fit();
1330 BOOST_TEST(s.capacity() < cap);
1331 });
1332 }
1333
1334 void
1335 testClear()
1336 {
1337 test_vectors const t;
1338
1339 // clear()
1340 {
1341 {
1342 string s(t.v1);
1343 s.clear();
1344 BOOST_TEST(s.empty());
1345 BOOST_TEST(s.size() == 0);
1346 BOOST_TEST(s.capacity() > 0);
1347 }
1348
1349 {
1350 string s(t.v2);
1351 s.clear();
1352 BOOST_TEST(s.empty());
1353 BOOST_TEST(s.size() == 0);
1354 BOOST_TEST(s.capacity() > 0);
1355 }
1356 }
1357 }
1358
1359 void
1360 testInsert()
1361 {
1362 test_vectors const t;
1363
1364 // insert(size_type, size_type, char)
1365 {
1366 fail_loop([&](storage_ptr const& sp)
1367 {
1368 string s(t.v1, sp);
1369 s.insert(1, 3, '*');
1370 BOOST_TEST(s == std::string(
1371 t.v1).insert(1, 3, '*'));
1372 });
1373
1374 fail_loop([&](storage_ptr const& sp)
1375 {
1376 string s(t.v2, sp);
1377 s.insert(1, 3, '*');
1378 BOOST_TEST(s == std::string(
1379 t.v2).insert(1, 3, '*'));
1380 });
1381
1382 // pos out of range
1383 {
1384 string s(t.v1);
1385 BOOST_TEST_THROWS(
1386 (s.insert(s.size() + 2, 1, '*')),
1387 std::out_of_range);
1388 }
1389
1390 // size > max_size
1391 {
1392 string s(t.v1);
1393 BOOST_TEST_THROWS(
1394 (s.insert(1, s.max_size(), 'a')),
1395 std::length_error);
1396 }
1397 }
1398
1399 // insert(size_type, char const*)
1400 {
1401 fail_loop([&](storage_ptr const& sp)
1402 {
1403 string s(t.v1, sp);
1404 s.insert(1, "***");
1405 BOOST_TEST(s == std::string(
1406 t.v1).insert(1, "***"));
1407 });
1408
1409 fail_loop([&](storage_ptr const& sp)
1410 {
1411 string s(t.v2, sp);
1412 s.insert(1, "***");
1413 BOOST_TEST(s == std::string(
1414 t.v2).insert(1, "***"));
1415 });
1416
1417 // pos out of range
1418 {
1419 string s(t.v1);
1420 BOOST_TEST_THROWS(
1421 (s.insert(s.size() + 2, "*")),
1422 std::out_of_range);
1423 }
1424 }
1425
1426 // insert(size_type, char const*, size_type)
1427 {
1428 fail_loop([&](storage_ptr const& sp)
1429 {
1430 string s(t.v1, sp);
1431 s.insert(1, "*****");
1432 BOOST_TEST(s == std::string(
1433 t.v1).insert(1, "*****"));
1434 });
1435
1436 fail_loop([&](storage_ptr const& sp)
1437 {
1438 string s(t.v2, sp);
1439 s.insert(1, "*****");
1440 BOOST_TEST(s == std::string(
1441 t.v2).insert(1, "*****"));
1442 });
1443 }
1444
1445 // insert(size_type, string const&)
1446 {
1447 fail_loop([&](storage_ptr const& sp)
1448 {
1449 string s(t.v1, sp);
1450 s.insert(1, string(t.v2));
1451 BOOST_TEST(s == std::string(
1452 t.v1).insert(1, t.s2));
1453 });
1454
1455 fail_loop([&](storage_ptr const& sp)
1456 {
1457 string s(t.v2, sp);
1458 s.insert(1, string(t.v1));
1459 BOOST_TEST(s == std::string(
1460 t.v2).insert(1, t.s1));
1461 });
1462 }
1463
1464 //// KRYSTIAN These tests are superseded by the new string_view overloads
1465 //// insert(size_type, string const&, size_type, size_type)
1466 //{
1467 // fail_loop([&](storage_ptr const& sp)
1468 // {
1469 // string s(t.v1, sp);
1470 // s.insert(1, string(t.v2), 1, 3);
1471 // BOOST_TEST(s == std::string(
1472 // t.v1).insert(1, t.s2, 1, 3));
1473 // });
1474
1475 // fail_loop([&](storage_ptr const& sp)
1476 // {
1477 // string s(t.v2, sp);
1478 // s.insert(1, string(t.v1), 1, 3);
1479 // BOOST_TEST(s == std::string(
1480 // t.v2).insert(1, t.s1, 1, 3));
1481 // });
1482
1483 // fail_loop([&](storage_ptr const& sp)
1484 // {
1485 // string s(t.v1, sp);
1486 // s.insert(1, string(t.v2), 1);
1487 // BOOST_TEST(s == std::string(
1488 // t.v1).insert(1, t.s2, 1, std::string::npos));
1489 // });
1490
1491 // fail_loop([&](storage_ptr const& sp)
1492 // {
1493 // string s(t.v2, sp);
1494 // s.insert(1, string(t.v1), 1);
1495 // BOOST_TEST(s == std::string(
1496 // t.v2).insert(1, t.s1, 1, std::string::npos));
1497 // });
1498 //}
1499
1500 // insert(size_type, char)
1501 {
1502 fail_loop([&](storage_ptr const& sp)
1503 {
1504 string s(t.v1, sp);
1505 BOOST_TEST(
1506 s.insert(2, '*')[2] == '*');
1507 });
1508
1509 fail_loop([&](storage_ptr const& sp)
1510 {
1511 string s(t.v2, sp);
1512 BOOST_TEST(
1513 s.insert(2, '*')[2] == '*');
1514 });
1515 }
1516
1517 // insert(const_iterator, size_type, char)
1518 {
1519 fail_loop([&](storage_ptr const& sp)
1520 {
1521 string s(t.v1, sp);
1522 BOOST_TEST(string_view(
1523 &(s.insert(2, 3, '*')[2]), 5) ==
1524 "***cd");
1525 });
1526
1527 fail_loop([&](storage_ptr const& sp)
1528 {
1529 string s(t.v2, sp);
1530 BOOST_TEST(string_view(
1531 &(s.insert(2, 3, '*')[2]), 5) ==
1532 "***CD");
1533 });
1534 }
1535
1536 // insert(const_iterator, InputIt, InputIt)
1537 {
1538 fail_loop([&](storage_ptr const& sp)
1539 {
1540 string s(t.v1, sp);
1541 s.insert(2, t.s2.begin(), t.s2.end());
1542 std::string cs(t.s1);
1543 cs.insert(2, &t.s2[0], t.s2.size());
1544 BOOST_TEST(s == cs);
1545 });
1546
1547 fail_loop([&](storage_ptr const& sp)
1548 {
1549 string s(t.v2, sp);
1550 s.insert(2, t.s1.begin(), t.s1.end());
1551 std::string cs(t.s2);
1552 cs.insert(2, &t.s1[0], t.s1.size());
1553 BOOST_TEST(s == cs);
1554 });
1555
1556 fail_loop([&](storage_ptr const& sp)
1557 {
1558 string s(t.v1, sp);
1559 s.insert(2,
1560 make_input_iterator(t.s2.begin()),
1561 make_input_iterator(t.s2.end()));
1562 std::string cs(t.s1);
1563 cs.insert(2, &t.s2[0], t.s2.size());
1564 BOOST_TEST(s == cs);
1565 });
1566
1567 fail_loop([&](storage_ptr const& sp)
1568 {
1569 string s(t.v2, sp);
1570 s.insert(2,
1571 make_input_iterator(t.s1.begin()),
1572 make_input_iterator(t.s1.end()));
1573 std::string cs(t.s2);
1574 cs.insert(2, &t.s1[0], t.s1.size());
1575 BOOST_TEST(s == cs);
1576 });
1577 }
1578
1579 // insert(const_iterator, string_view)
1580 {
1581 fail_loop([&](storage_ptr const& sp)
1582 {
1583 string s(t.v1, sp);
1584 s.insert(2, string_view(t.v2));
1585 std::string cs(t.v1);
1586 cs.insert(2, t.s2);
1587 BOOST_TEST(s == cs);
1588 });
1589
1590 fail_loop([&](storage_ptr const& sp)
1591 {
1592 string s(t.v2, sp);
1593 s.insert(2, string_view(t.v1));
1594 std::string cs(t.v2);
1595 cs.insert(2, t.s1);
1596 BOOST_TEST(s == cs);
1597 });
1598 }
1599
1600 // insert(const_iterator, string_view)
1601 {
1602 fail_loop([&](storage_ptr const& sp)
1603 {
1604 string s(t.v1, sp);
1605 s.insert(2, string_view(t.v2).substr(2, 3));
1606 std::string cs(t.v1);
1607 cs.insert(2, t.s2, 2, 3);
1608 BOOST_TEST(s == cs);
1609 });
1610
1611 fail_loop([&](storage_ptr const& sp)
1612 {
1613 string s(t.v2, sp);
1614 s.insert(2, string_view(t.v1).substr(2, 3));
1615 std::string cs(t.v2);
1616 cs.insert(2, t.s1, 2, 3);
1617 BOOST_TEST(s == cs);
1618 });
1619 }
1620
1621 // insert(size_type, char const*)
1622 {
1623 fail_loop([&](storage_ptr const& sp)
1624 {
1625 string s(t.v1, sp);
1626 s.insert(1, "***");
1627 BOOST_TEST(s == std::string(
1628 t.v1).insert(1, "***"));
1629 });
1630
1631 fail_loop([&](storage_ptr const& sp)
1632 {
1633 string s(t.v2, sp);
1634 s.insert(1, "***");
1635 BOOST_TEST(s == std::string(
1636 t.v2).insert(1, "***"));
1637 });
1638
1639 // pos out of range
1640 {
1641 string s(t.v1);
1642 BOOST_TEST_THROWS(
1643 (s.insert(s.size() + 2, "*")),
1644 std::out_of_range);
1645 }
1646 }
1647
1648 // insert tests for when source is within destination
1649 {
1650 // start before splice point
1651 fail_loop([&](storage_ptr const& sp)
1652 {
1653 string s(t.v1, sp);
1654 s.reserve(s.size() + 10);
1655 s.insert(4, s.subview(0, 3));
1656 std::string cs(t.v1);
1657 cs.insert(4, cs.substr(0, 3));
1658 BOOST_TEST(s == cs);
1659 });
1660
1661 // start after splice point
1662 fail_loop([&](storage_ptr const& sp)
1663 {
1664 string s(t.v1, sp);
1665 s.reserve(s.size() + 10);
1666 s.insert(0, s.subview(3, 3));
1667 std::string cs(t.v1);
1668 cs.insert(0, cs.substr(3, 3));
1669 BOOST_TEST(s == cs);
1670 });
1671
1672 // insert pos bisects the inserted string
1673 fail_loop([&](storage_ptr const& sp)
1674 {
1675 string s(t.v1, sp);
1676 s.reserve(s.size() + 10);
1677 s.insert(2, s.subview(0, 5));
1678 std::string cs(t.v1);
1679 cs.insert(2, cs.substr(0, 5));
1680 BOOST_TEST(s == cs);
1681 });
1682 }
1683
1684 // insert reallocation test
1685 {
1686 fail_loop([&](storage_ptr const& sp)
1687 {
1688 string s(t.v2, sp);
1689 std::string cs(t.v2);
1690 const auto view = t.v2.substr(0, 4);
1691 s.append(s);
1692 cs.append(cs);
1693 s.insert(2, view);
1694 cs.insert(2, view.data(), view.size());
1695 BOOST_TEST(s == cs);
1696 });
1697 }
1698 }
1699
1700 void
1701 testErase()
1702 {
1703 test_vectors const t;
1704
1705 // erase(size_type, size_type)
1706 {
1707 {
1708 string s(t.v1);
1709 s.erase(1, 3);
1710 BOOST_TEST(s ==
1711 std::string(t.v1).erase(1, 3));
1712 }
1713
1714 {
1715 string s(t.v2);
1716 s.erase(1, 3);
1717 BOOST_TEST(s ==
1718 std::string(t.v2).erase(1, 3));
1719 }
1720
1721 {
1722 string s(t.v1);
1723 s.erase(3);
1724 BOOST_TEST(s ==
1725 std::string(t.v1).erase(3));
1726 }
1727
1728 {
1729 string s(t.v2);
1730 s.erase(3);
1731 BOOST_TEST(s ==
1732 std::string(t.v2).erase(3));
1733 }
1734
1735 {
1736 string s(t.v1);
1737 s.erase();
1738 BOOST_TEST(s ==
1739 std::string(t.v1).erase());
1740 }
1741
1742 {
1743 string s(t.v2);
1744 s.erase();
1745 BOOST_TEST(s ==
1746 std::string(t.v2).erase());
1747 }
1748
1749 {
1750 string s(t.v1);
1751 BOOST_TEST_THROWS(
1752 (s.erase(t.v1.size() + 1, 1)),
1753 std::out_of_range);
1754 }
1755 }
1756
1757 // iterator erase(const_iterator)
1758 {
1759 {
1760 string s(t.v1);
1761 std::string s2(t.v1);
1762 s.erase(s.begin() + 3);
1763 s2.erase(s2.begin() + 3);
1764 BOOST_TEST(s == s2);
1765 }
1766
1767 {
1768 string s(t.v2);
1769 std::string s2(t.v2);
1770 s.erase(s.begin() + 3);
1771 s2.erase(s2.begin() + 3);
1772 BOOST_TEST(s == s2);
1773 }
1774 }
1775
1776 // iterator erase(const_iterator, const_iterator)
1777 {
1778 string s(t.v1);
1779 std::string s2(t.v1);
1780 s.erase(s.begin() + 1, s.begin() + 3);
1781 s2.erase(s2.begin() + 1, s2.begin() + 3);
1782 BOOST_TEST(s == s2);
1783 }
1784 }
1785
1786 void
1787 testPushPop()
1788 {
1789 test_vectors const t;
1790
1791 // push_back(char)
1792 {
1793 fail_loop([&](storage_ptr const& sp)
1794 {
1795 string s(sp);
1796 for(auto ch : t.v1)
1797 s.push_back(ch);
1798 BOOST_TEST(s == t.v1);
1799 });
1800
1801 fail_loop([&](storage_ptr const& sp)
1802 {
1803 string s(sp);
1804 for(auto ch : t.v2)
1805 s.push_back(ch);
1806 BOOST_TEST(s == t.v2);
1807 });
1808 }
1809
1810 // pop_back(char)
1811 {
1812 {
1813 string s(t.v1);
1814 while(! s.empty())
1815 s.pop_back();
1816 BOOST_TEST(s.empty());
1817 BOOST_TEST(s.capacity() > 0);
1818 }
1819
1820 {
1821 string s(t.v2);
1822 while(! s.empty())
1823 s.pop_back();
1824 BOOST_TEST(s.empty());
1825 BOOST_TEST(s.capacity() > 0);
1826 }
1827 }
1828 }
1829
1830 void
1831 testAppend()
1832 {
1833 test_vectors const t;
1834
1835 // append(size_type, char)
1836 {
1837 fail_loop([&](storage_ptr const& sp)
1838 {
1839 string s(t.v1, sp);
1840 s.append(t.v2.size(), '*');
1841 BOOST_TEST(s == t.s1 +
1842 std::string(t.v2.size(), '*'));
1843 });
1844
1845 fail_loop([&](storage_ptr const& sp)
1846 {
1847 string s(t.v2, sp);
1848 s.append(t.v1.size(), '*');
1849 BOOST_TEST(s == t.s2 +
1850 std::string(t.v1.size(), '*'));
1851 });
1852 }
1853
1854 // append(string_view)
1855 {
1856 fail_loop([&](storage_ptr const& sp)
1857 {
1858 string s(t.v1, sp);
1859 s.append(string(t.v2));
1860 BOOST_TEST(s == t.s1 + t.s2);
1861 });
1862
1863 fail_loop([&](storage_ptr const& sp)
1864 {
1865 string s(t.v2, sp);
1866 s.append(string(t.v1));
1867 BOOST_TEST(s == t.s2 + t.s1);
1868 });
1869 }
1870
1871 // append(string_view)
1872 {
1873 fail_loop([&](storage_ptr const& sp)
1874 {
1875 string s(t.v1, sp);
1876 s.append(string(t.v2).subview(3));
1877 BOOST_TEST(s == t.s1 + t.s2.substr(3));
1878 });
1879
1880 fail_loop([&](storage_ptr const& sp)
1881 {
1882 string s(t.v2, sp);
1883 s.append(string(t.v1).subview(3));
1884 BOOST_TEST(s == t.s2 + t.s1.substr(3));
1885 });
1886
1887 fail_loop([&](storage_ptr const& sp)
1888 {
1889 string s(t.v1, sp);
1890 s.append(string(t.v2).subview(2, 3));
1891 BOOST_TEST(s == t.s1 + t.s2.substr(2, 3));
1892 });
1893
1894 fail_loop([&](storage_ptr const& sp)
1895 {
1896 string s(t.v2, sp);
1897 s.append(string(t.v1).subview(2, 3));
1898 BOOST_TEST(s == t.s2 + t.s1.substr(2, 3));
1899 });
1900 }
1901
1902 // append(char const*)
1903 {
1904 fail_loop([&](storage_ptr const& sp)
1905 {
1906 string s(t.v1, sp);
1907 s.append(t.s2.c_str());
1908 BOOST_TEST(s == t.s1 + t.s2);
1909 });
1910
1911 fail_loop([&](storage_ptr const& sp)
1912 {
1913 string s(t.v2, sp);
1914 s.append(t.s1.c_str());
1915 BOOST_TEST(s == t.s2 + t.s1);
1916 });
1917 }
1918
1919 // append(InputIt, InputIt)
1920 {
1921 fail_loop([&](storage_ptr const& sp)
1922 {
1923 string s(t.v1, sp);
1924 s.append(t.s2.begin(), t.s2.end());
1925 BOOST_TEST(s == t.s1 + t.s2);
1926 });
1927
1928 fail_loop([&](storage_ptr const& sp)
1929 {
1930 string s(t.v2, sp);
1931 s.append(t.s1.begin(), t.s1.end());
1932 BOOST_TEST(s == t.s2 + t.s1);
1933 });
1934
1935 // Fails on Visual Studio 2017 C++2a Strict
1936 fail_loop([&](storage_ptr const& sp)
1937 {
1938 string s(t.v1, sp);
1939 s.append(
1940 make_input_iterator(t.s2.begin()),
1941 make_input_iterator(t.s2.end()));
1942 BOOST_TEST(s == t.s1 + t.s2);
1943 });
1944
1945 fail_loop([&](storage_ptr const& sp)
1946 {
1947 string s(t.v2, sp);
1948 s.append(
1949 make_input_iterator(t.s1.begin()),
1950 make_input_iterator(t.s1.end()));
1951 BOOST_TEST(s == t.s2 + t.s1);
1952 });
1953 }
1954
1955 // append(string_view)
1956 {
1957 fail_loop([&](storage_ptr const& sp)
1958 {
1959 string s(t.v1, sp);
1960 s.append(t.v2);
1961 BOOST_TEST(s == t.s1 + t.s2);
1962 });
1963
1964 fail_loop([&](storage_ptr const& sp)
1965 {
1966 string s(t.v2, sp);
1967 s.append(t.v1);
1968 BOOST_TEST(s == t.s2 + t.s1);
1969 });
1970 }
1971
1972 // append(string_view)
1973 {
1974 fail_loop([&](storage_ptr const& sp)
1975 {
1976 string s(t.v1, sp);
1977 s.append(t.v2.substr(2));
1978 BOOST_TEST(s == t.s1 + t.s2.substr(2));
1979 });
1980
1981 fail_loop([&](storage_ptr const& sp)
1982 {
1983 string s(t.v2, sp);
1984 s.append(t.v1.substr(2));
1985 BOOST_TEST(s == t.s2 + t.s1.substr(2));
1986 });
1987
1988 fail_loop([&](storage_ptr const& sp)
1989 {
1990 string s(t.v1, sp);
1991 s.append(t.v2.substr(2, 3));
1992 BOOST_TEST(s == t.s1 + t.s2.substr(2, 3));
1993 });
1994
1995 fail_loop([&](storage_ptr const& sp)
1996 {
1997 string s(t.v2, sp);
1998 s.append(t.v1.substr(2, 3));
1999 BOOST_TEST(s == t.s2 + t.s1.substr(2, 3));
2000 });
2001 }
2002 }
2003
2004 void
2005 testPlusEquals()
2006 {
2007 test_vectors const t;
2008
2009 // operator+=(string)
2010 {
2011 fail_loop([&](storage_ptr const& sp)
2012 {
2013 string s(t.v1, sp);
2014 s += string(t.v2);
2015 BOOST_TEST(s == t.s1 + t.s2);
2016 });
2017
2018 fail_loop([&](storage_ptr const& sp)
2019 {
2020 string s(t.v2, sp);
2021 s += string(t.v1);
2022 BOOST_TEST(s == t.s2 + t.s1);
2023 });
2024 }
2025
2026 // operator+=(char)
2027 {
2028 fail_loop([&](storage_ptr const& sp)
2029 {
2030 string s(sp);
2031 for(auto ch : t.v1)
2032 s += ch;
2033 BOOST_TEST(s == t.v1);
2034 });
2035
2036 fail_loop([&](storage_ptr const& sp)
2037 {
2038 string s(sp);
2039 for(auto ch : t.v2)
2040 s += ch;
2041 BOOST_TEST(s == t.v2);
2042 });
2043 }
2044
2045 // operator+=(char const*)
2046 {
2047 fail_loop([&](storage_ptr const& sp)
2048 {
2049 string s(t.v1, sp);
2050 s += t.s2.c_str();
2051 BOOST_TEST(s == t.s1 + t.s2);
2052 });
2053
2054 fail_loop([&](storage_ptr const& sp)
2055 {
2056 string s(t.v2, sp);
2057 s += t.s1.c_str();
2058 BOOST_TEST(s == t.s2 + t.s1);
2059 });
2060 }
2061
2062 // operator+=(string_view)
2063 {
2064 fail_loop([&](storage_ptr const& sp)
2065 {
2066 string s(t.v1, sp);
2067 s += t.v2;
2068 BOOST_TEST(s == t.s1 + t.s2);
2069 });
2070
2071 fail_loop([&](storage_ptr const& sp)
2072 {
2073 string s(t.v2, sp);
2074 s += t.v1;
2075 BOOST_TEST(s == t.s2 + t.s1);
2076 });
2077 }
2078 }
2079
2080 void
2081 testCompare()
2082 {
2083 test_vectors const t;
2084 string const v1 = t.v1;
2085
2086 // compare(string)
2087 BOOST_TEST(v1.compare(string("aaaaaaa")) > 0);
2088 BOOST_TEST(v1.compare(string(t.v1)) == 0);
2089 BOOST_TEST(v1.compare(string("bbbbbbb")) < 0);
2090
2091 // compare(char const*)
2092 BOOST_TEST(v1.compare("aaaaaaa") > 0);
2093 BOOST_TEST(v1.compare(t.s1.c_str()) == 0);
2094 BOOST_TEST(v1.compare("bbbbbbb") < 0);
2095
2096 // compare(string_view s)
2097 BOOST_TEST(v1.compare(string_view("aaaaaaa")) > 0);
2098 BOOST_TEST(v1.compare(t.v1) == 0);
2099 BOOST_TEST(v1.compare(string_view("bbbbbbb")) < 0);
2100 }
2101
2102 void
2103 testStartEndsWith()
2104 {
2105 test_vectors const t;
2106 string const v1 = t.v1;
2107 string const v2 = t.v2;
2108
2109 // starts_with(string_view)
2110 {
2111 BOOST_TEST(v1.starts_with(string_view("abc")));
2112 BOOST_TEST(v2.starts_with(string_view("ABC")));
2113 BOOST_TEST(! v1.starts_with(string_view("xyz")));
2114 BOOST_TEST(! v2.starts_with(string_view("XYZ")));
2115 }
2116
2117 // starts_with(char)
2118 {
2119 BOOST_TEST(v1.starts_with('a'));
2120 BOOST_TEST(v2.starts_with('A'));
2121 BOOST_TEST(! v1.starts_with('x'));
2122 BOOST_TEST(! v2.starts_with('X'));
2123 }
2124
2125 // starts_with(char const*)
2126 {
2127 BOOST_TEST(v1.starts_with("abc"));
2128 BOOST_TEST(v2.starts_with("ABC"));
2129 BOOST_TEST(! v1.starts_with("xyz"));
2130 BOOST_TEST(! v2.starts_with("XYZ"));
2131 }
2132
2133 // ends_with(string_view)
2134 {
2135 BOOST_TEST(v1.ends_with(last_of(t.s1,3)));
2136 BOOST_TEST(v2.ends_with(last_of(t.s2,3)));
2137 BOOST_TEST(! v1.ends_with(string_view("abc")));
2138 BOOST_TEST(! v2.ends_with(string_view("ABC")));
2139 }
2140
2141 // ends_with(char)
2142 {
2143 BOOST_TEST(v1.ends_with(last_of(t.s1, 1)[0]));
2144 BOOST_TEST(v2.ends_with(last_of(t.s2, 1)[0]));
2145 BOOST_TEST(! v1.ends_with('a'));
2146 BOOST_TEST(! v2.ends_with('A'));
2147 }
2148
2149 // ends_with(char const*)
2150 {
2151 BOOST_TEST(v1.ends_with(last_of(t.s1, 3).data()));
2152 BOOST_TEST(v2.ends_with(last_of(t.s2, 3).data()));
2153 BOOST_TEST(! v1.ends_with("abc"));
2154 BOOST_TEST(! v2.ends_with("ABC"));
2155 }
2156 }
2157
2158 void
2159 testReplace()
2160 {
2161 test_vectors const t;
2162
2163 // replace(std::size_t, std::size_t, string_view)
2164 {
2165 // pos out of range
2166 fail_loop([&](storage_ptr const& sp)
2167 {
2168 string s(t.v2, sp);
2169 BOOST_TEST_THROWS(s.replace(s.size() + 1, 1, t.v2),
2170 std::out_of_range);
2171 });
2172
2173 // outside, shrink
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, 4, t.v2.substr(4, 2)) ==
2179 s1.replace(0, 4, t.v2.data() + 4, 2));
2180 });
2181
2182 // outside, grow
2183 fail_loop([&](storage_ptr const& sp)
2184 {
2185 std::string s1(t.v2.data(), t.v2.size());
2186 string s2(t.v2, sp);
2187 BOOST_TEST(s2.replace(0, 1, t.v2.substr(0)) ==
2188 s1.replace(0, 1, t.v2.data(), t.v2.size()));
2189 });
2190
2191 // outside, grow, reallocate
2192 fail_loop([&](storage_ptr const& sp)
2193 {
2194 std::string s1(t.v2.data(), t.v2.size());
2195 string s2(t.v2, sp);
2196 s1.append(s1);
2197 s2.append(s2);
2198 BOOST_TEST(s2.replace(0, 1, t.v2.substr(0)) ==
2199 s1.replace(0, 1, t.v2.data(), t.v2.size()));
2200 });
2201
2202 // outside, same
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(0, 2, t.v2.substr(0, 2)) ==
2208 s1.replace(0, 2, t.v2.data(), 2));
2209 });
2210
2211 // replace tests for full coverage
2212
2213 // inside, no effect
2214 fail_loop([&](storage_ptr const& sp)
2215 {
2216 std::string s1(t.v2.data(), t.v2.size());
2217 string s2(t.v2, sp);
2218 BOOST_TEST(s2.replace(0, 4, s2.subview(0, 4)) ==
2219 s1.replace(0, 4, s1.data() + 0, 4));
2220 });
2221
2222 // inside, shrink, 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, 4, s2.subview(4, 2)) ==
2228 s1.replace(1, 4, s1.data() + 4, 2));
2229 });
2230
2231 // inside, grow no reallocate, split
2232 fail_loop([&](storage_ptr const& sp)
2233 {
2234 std::string s1(t.v2.data(), t.v2.size());
2235 string s2(t.v2, sp);
2236 BOOST_TEST(s2.replace(1, 1, s2.subview(0)) ==
2237 s1.replace(1, 1, s1.data(), s1.size()));
2238 });
2239
2240 // inside, reallocate, split
2241 fail_loop([&](storage_ptr const& sp)
2242 {
2243 std::string s1(t.v2.data(), t.v2.size());
2244 string s2(t.v2, sp);
2245 s1.append(s1);
2246 s2.append(s2);
2247 BOOST_TEST(s2.replace(1, 1, s2.subview(0)) ==
2248 s1.replace(1, 1, s1.data(), s1.size()));
2249 });
2250
2251 // inside, same, split
2252 fail_loop([&](storage_ptr const& sp)
2253 {
2254 std::string s1(t.v2.data(), t.v2.size());
2255 string s2(t.v2, sp);
2256 BOOST_TEST(s2.replace(1, 2, s2.subview(0, 2)) ==
2257 s1.replace(1, 2, s1.data(), 2));
2258 });
2259 }
2260
2261 // replace(const_iterator, const_iterator, string_view)
2262 {
2263 // outside, shrink
2264 fail_loop([&](storage_ptr const& sp)
2265 {
2266 std::string s1(t.v2.data(), t.v2.size());
2267 string s2(t.v2, sp);
2268 BOOST_TEST(
2269 s2.replace(
2270 s2.begin(),
2271 s2.begin() + 4,
2272 t.v2.substr(4, 2)) ==
2273 s1.replace(0,
2274 4, t.v2.data() + 4,
2275 2));
2276 });
2277
2278 // outside, grow
2279 fail_loop([&](storage_ptr const& sp)
2280 {
2281 std::string s1(t.v2.data(), t.v2.size());
2282 string s2(t.v2, sp);
2283 BOOST_TEST(
2284 s2.replace(
2285 s2.begin(),
2286 s2.begin() + 1,
2287 t.v2.substr(0)) ==
2288 s1.replace(0,
2289 1, t.v2.data(),
2290 t.v2.size()));
2291 });
2292
2293 // outside, same
2294 fail_loop([&](storage_ptr const& sp)
2295 {
2296 std::string s1(t.v2.data(), t.v2.size());
2297 string s2(t.v2, sp);
2298 BOOST_TEST(
2299 s2.replace(
2300 s2.begin(),
2301 s2.begin() + 2,
2302 t.v2.substr(0, 2)) ==
2303 s1.replace(
2304 0, 2,
2305 t.v2.data(),
2306 2));
2307 });
2308
2309 // inside, shrink
2310 fail_loop([&](storage_ptr const& sp)
2311 {
2312 std::string s1(t.v2.data(), t.v2.size());
2313 string s2(t.v2, sp);
2314 BOOST_TEST(
2315 s2.replace(
2316 s2.begin() + 1,
2317 s2.begin() + 5,
2318 s2.subview(4, 2)) ==
2319 s1.replace(
2320 1, 4,
2321 s1.data() + 4,
2322 2));
2323 });
2324
2325 // inside, grow
2326 fail_loop([&](storage_ptr const& sp)
2327 {
2328 std::string s1(t.v2.data(), t.v2.size());
2329 string s2(t.v2, sp);
2330 BOOST_TEST(
2331 s2.replace(
2332 s2.begin() + 1,
2333 s2.begin() + 2,
2334 s2.subview(0)) ==
2335 s1.replace(
2336 1, 1,
2337 s1.data(),
2338 s1.size()));
2339 });
2340
2341 // inside, same
2342 fail_loop([&](storage_ptr const& sp)
2343 {
2344 std::string s1(t.v2.data(), t.v2.size());
2345 string s2(t.v2, sp);
2346 BOOST_TEST(
2347 s2.replace(
2348 s2.begin() + 1,
2349 s2.begin() + 3,
2350 s2.subview(0, 2)) ==
2351 s1.replace(
2352 1, 2,
2353 s1.data(),
2354 2));
2355 });
2356 }
2357
2358 // replace(std::size_t, std::size_t, std::size_t, char)
2359 {
2360 // grow, no realloc
2361 fail_loop([&](storage_ptr const& sp)
2362 {
2363 std::string s1(t.v2.data(), t.v2.size());
2364 string s2(t.v2, sp);
2365 BOOST_TEST(s2.replace(0, 4, 10, 'a') ==
2366 s1.replace(0, 4, 10, 'a'));
2367 });
2368
2369 // grow, realloc
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 const auto grow = (std::max)(s1.capacity(), s2.capacity());
2375 BOOST_TEST(s2.replace(0, 4, grow, 'a') ==
2376 s1.replace(0, 4, grow, 'a'));
2377 });
2378
2379 // no change in size
2380 fail_loop([&](storage_ptr const& sp)
2381 {
2382 std::string s1(t.v2.data(), t.v2.size());
2383 string s2(t.v2, sp);
2384 BOOST_TEST(s2.replace(0, 1, 1, 'a') ==
2385 s1.replace(0, 1, 1, 'a'));
2386 });
2387
2388 // pos out of range
2389 fail_loop([&](storage_ptr const& sp)
2390 {
2391 string s(t.v2, sp);
2392 BOOST_TEST_THROWS(s.replace(s.size() + 1, 1, 1, 'a'),
2393 std::out_of_range);
2394 });
2395 }
2396
2397 // replace(const_iterator, const_iterator, std::size_t, char)
2398 {
2399 fail_loop([&](storage_ptr const& sp)
2400 {
2401 std::string s1(t.v2.data(), t.v2.size());
2402 string s2(t.v2, sp);
2403 BOOST_TEST(
2404 s2.replace(s2.begin(), s2.begin() + 4, 10, 'a') ==
2405 s1.replace(0, 4, 10, 'a'));
2406 });
2407 }
2408 }
2409
2410 void
2411 testSubStr()
2412 {
2413 test_vectors const t;
2414 string const s1 = t.v1;
2415 string const s2 = t.v2;
2416
2417 // subview(size_type, size_type)
2418 BOOST_TEST(s1.subview() == t.v1);
2419 BOOST_TEST(s1.subview(1) == t.v1.substr(1));
2420 BOOST_TEST(s1.subview(1, 3) == t.v1.substr(1, 3));
2421 BOOST_TEST(s2.subview() == t.v2);
2422 BOOST_TEST(s2.subview(1) == t.v2.substr(1));
2423 BOOST_TEST(s2.subview(1, 3) == t.v2.substr(1, 3));
2424 }
2425
2426 void
2427 testCopy()
2428 {
2429 test_vectors const t;
2430
2431 // copy(char*, count, pos)
2432 {
2433 {
2434 string s(t.v1);
2435 std::string d;
2436 d.resize(s.size());
2437 s.copy(&d[0], d.size(), 0);
2438 BOOST_TEST(d == t.v1);
2439 }
2440
2441 {
2442 string s(t.v1);
2443 std::string d;
2444 d.resize(s.size());
2445 s.copy(&d[0], d.size());
2446 BOOST_TEST(d == t.v1);
2447 }
2448 }
2449 }
2450
2451 void
2452 testResize()
2453 {
2454 test_vectors const t;
2455
2456 // resize(size_type)
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(), '\0'));
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(), '\0'));
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(), '\0'));
2480 s.resize(t.v1.size());
2481 BOOST_TEST(s == string(t.v1.size(), '\0'));
2482 });
2483 }
2484
2485 // resize(size_type, char)
2486 {
2487 fail_loop([&](storage_ptr const& sp)
2488 {
2489 string s(sp);
2490 s.resize(t.v1.size(), '*');
2491 BOOST_TEST(s.size() == t.v1.size());
2492 BOOST_TEST(s == string(t.v1.size(), '*'));
2493 });
2494
2495 fail_loop([&](storage_ptr const& sp)
2496 {
2497 string s(sp);
2498 s.resize(t.v2.size(), '*');
2499 BOOST_TEST(s.size() == t.v2.size());
2500 BOOST_TEST(s == string(t.v2.size(), '*'));
2501 });
2502
2503 fail_loop([&](storage_ptr const& sp)
2504 {
2505 string s(sp);
2506 s.resize(t.v1.size(), '*');
2507 s.resize(t.v2.size(), '*');
2508 BOOST_TEST(s == string(t.v2.size(), '*'));
2509 s.resize(t.v1.size());
2510 BOOST_TEST(s == string(t.v1.size(), '*'));
2511 });
2512 }
2513 }
2514
2515 void
2516 testSwap()
2517 {
2518 test_vectors const t;
2519
2520 // swap
2521 {
2522 fail_loop([&](storage_ptr const& sp)
2523 {
2524 string s1(t.v1, sp);
2525 string s2(t.v2, sp);
2526 s1.swap(s2);
2527 BOOST_TEST(s1 == t.v2);
2528 BOOST_TEST(s2 == t.v1);
2529 });
2530
2531 fail_loop([&](storage_ptr const& sp)
2532 {
2533 string s1(t.v1, sp);
2534 string s2(t.v2, sp);
2535 swap(s1, s2);
2536 BOOST_TEST(s1 == t.v2);
2537 BOOST_TEST(s2 == t.v1);
2538 });
2539
2540 fail_loop([&](storage_ptr const& sp)
2541 {
2542 string s1(t.v1);
2543 string s2(t.v2, sp);
2544 s1.swap(s2);
2545 BOOST_TEST(s1 == t.v2);
2546 BOOST_TEST(s2 == t.v1);
2547 });
2548 }
2549 }
2550
2551 void
2552 testFind()
2553 {
2554 test_vectors const t;
2555 string const s1 = t.v1;
2556
2557 // find(string_view, size_type)
2558 BOOST_TEST(s1.find("bcd") == 1);
2559 BOOST_TEST(s1.find("cde") == 2);
2560
2561 BOOST_TEST(s1.find("bcd", 0) == 1);
2562 BOOST_TEST(s1.find("cde", 1) == 2);
2563 BOOST_TEST(s1.find("efg", 5) == string::npos);
2564
2565 // find(char, size_type)
2566 BOOST_TEST(s1.find('b') == 1);
2567 BOOST_TEST(s1.find('c', 1) == 2);
2568 BOOST_TEST(s1.find('e', 5) == string::npos);
2569 }
2570
2571 void
2572 testRfind()
2573 {
2574 test_vectors const t;
2575 string const s1 = t.v1;
2576
2577 // rfind(string_view, size_type)
2578 BOOST_TEST(s1.rfind("bcd") == 1);
2579 BOOST_TEST(s1.rfind("cde") == 2);
2580
2581 BOOST_TEST(s1.rfind("bcd", 1) == 1);
2582 BOOST_TEST(s1.rfind("cde", 2) == 2);
2583 BOOST_TEST(s1.rfind("efg", 3) == string::npos);
2584
2585 // rfind(char, size_type)
2586 BOOST_TEST(s1.rfind('b') == 1);
2587 BOOST_TEST(s1.rfind('c', 2) == 2);
2588 BOOST_TEST(s1.rfind('e', 3) == string::npos);
2589 }
2590
2591 void
2592 testFindFirstOf()
2593 {
2594 test_vectors const t;
2595 string const s1 = t.v1;
2596
2597 // find_first_of(string_view, size_type)
2598 BOOST_TEST(s1.find_first_of("bcd") == 1);
2599 BOOST_TEST(s1.find_first_of("cde") == 2);
2600
2601 BOOST_TEST(s1.find_first_of("bcd", 0) == 1);
2602 BOOST_TEST(s1.find_first_of("cde", 1) == 2);
2603 BOOST_TEST(s1.find_first_of("efg", 7) == string::npos);
2604 }
2605
2606 void
2607 testFindFirstNotOf()
2608 {
2609 test_vectors const t;
2610 string const s1 = t.v1;
2611
2612 // find_first_not_of(string_view, size_type)
2613 BOOST_TEST(s1.find_first_not_of("abc") == 3);
2614 BOOST_TEST(s1.find_first_not_of("cde") == 0);
2615
2616 BOOST_TEST(s1.find_first_not_of("bcd", 0) == 0);
2617 BOOST_TEST(s1.find_first_not_of("cde", 2) == 5);
2618
2619 // find_first_not_of(char, size_type)
2620 BOOST_TEST(s1.find_first_not_of('b') == 0);
2621 BOOST_TEST(s1.find_first_not_of('a', 0) == 1);
2622 BOOST_TEST(s1.find_first_not_of('e', 4) == 5);
2623 }
2624
2625 void
2626 testFindLastOf()
2627 {
2628 test_vectors const t;
2629 string const s1 = t.v1;
2630
2631 // find_last_of(string_view, size_type)
2632 BOOST_TEST(s1.find_last_of("bcd") == 3);
2633 BOOST_TEST(s1.find_last_of("cde") == 4);
2634
2635 BOOST_TEST(s1.find_last_of("bcd", 3) == 3);
2636 BOOST_TEST(s1.find_last_of("cde", 5) == 4);
2637 BOOST_TEST(s1.find_last_of("efg", 3) == string::npos);
2638 }
2639
2640 void
2641 testFindLastNotOf()
2642 {
2643 test_vectors const t;
2644 string const s1 = t.v1;
2645
2646 // find_last_not_of(string_view, size_type)
2647 BOOST_TEST(s1.find_last_not_of("abc", 3) == 3);
2648 BOOST_TEST(s1.find_last_not_of("bcd", 3) == 0);
2649
2650 BOOST_TEST(s1.find_last_not_of("efg", 4) == 3);
2651 BOOST_TEST(s1.find_last_not_of("abc", 2) == string::npos);
2652
2653 // find_first_not_of(char, size_type)
2654 BOOST_TEST(s1.find_last_not_of('a', 3) == 3);
2655 BOOST_TEST(s1.find_last_not_of('e', 4) == 3);
2656 BOOST_TEST(s1.find_last_not_of('a', 0) == string::npos);
2657 }
2658
2659 void
2660 testNonMembers()
2661 {
2662 test_vectors const t;
2663 string const s1(t.v1);
2664 string const s2(t.v2);
2665 auto const v1(t.v1);
2666 auto const v2(t.v2);
2667 auto const c1 = t.s1.c_str();
2668 auto const c2 = t.s2.c_str();
2669
2670 BOOST_TEST(! operator< (s1, s2));
2671 BOOST_TEST(! operator< (s1, v2));
2672 BOOST_TEST(! operator< (s1, c2));
2673 BOOST_TEST(! operator<=(s1, s2));
2674 BOOST_TEST(! operator<=(s1, v2));
2675 BOOST_TEST(! operator<=(s1, c2));
2676 BOOST_TEST(! operator==(s1, s2));
2677 BOOST_TEST(! operator==(s1, v2));
2678 BOOST_TEST(! operator==(s1, c2));
2679 BOOST_TEST( operator!=(s1, s2));
2680 BOOST_TEST( operator!=(s1, v2));
2681 BOOST_TEST( operator!=(s1, c2));
2682 BOOST_TEST( operator>=(s1, s2));
2683 BOOST_TEST( operator>=(s1, v2));
2684 BOOST_TEST( operator>=(s1, c2));
2685 BOOST_TEST( operator> (s1, s2));
2686 BOOST_TEST( operator> (s1, v2));
2687 BOOST_TEST( operator> (s1, c2));
2688
2689 BOOST_TEST( operator< (s2, s1));
2690 BOOST_TEST( operator< (s2, v1));
2691 BOOST_TEST( operator< (s2, c1));
2692 BOOST_TEST( operator<=(s2, s1));
2693 BOOST_TEST( operator<=(s2, v1));
2694 BOOST_TEST( operator<=(s2, c1));
2695 BOOST_TEST( operator!=(s2, s1));
2696 BOOST_TEST( operator!=(s2, v1));
2697 BOOST_TEST( operator!=(s2, c1));
2698 BOOST_TEST(! operator==(s2, s1));
2699 BOOST_TEST(! operator==(s2, v1));
2700 BOOST_TEST(! operator==(s2, c1));
2701 BOOST_TEST(! operator>=(s2, s1));
2702 BOOST_TEST(! operator>=(s2, v1));
2703 BOOST_TEST(! operator>=(s2, c1));
2704 BOOST_TEST(! operator> (s2, s1));
2705 BOOST_TEST(! operator> (s2, v1));
2706 BOOST_TEST(! operator> (s2, c1));
2707
2708 BOOST_TEST( operator< (s2, s1));
2709 BOOST_TEST( operator< (v2, s1));
2710 BOOST_TEST( operator< (c2, s1));
2711 BOOST_TEST( operator<=(s2, s1));
2712 BOOST_TEST( operator<=(v2, s1));
2713 BOOST_TEST( operator<=(c2, s1));
2714 BOOST_TEST( operator!=(s2, s1));
2715 BOOST_TEST( operator!=(v2, s1));
2716 BOOST_TEST( operator!=(c2, s1));
2717 BOOST_TEST(! operator==(s2, s1));
2718 BOOST_TEST(! operator==(v2, s1));
2719 BOOST_TEST(! operator==(c2, s1));
2720 BOOST_TEST(! operator>=(s2, s1));
2721 BOOST_TEST(! operator>=(v2, s1));
2722 BOOST_TEST(! operator>=(c2, s1));
2723 BOOST_TEST(! operator> (s2, s1));
2724 BOOST_TEST(! operator> (v2, s1));
2725 BOOST_TEST(! operator> (c2, s1));
2726
2727 BOOST_TEST(! operator< (s1, s2));
2728 BOOST_TEST(! operator< (v1, s2));
2729 BOOST_TEST(! operator< (c1, s2));
2730 BOOST_TEST(! operator<=(s1, s2));
2731 BOOST_TEST(! operator<=(v1, s2));
2732 BOOST_TEST(! operator<=(c1, s2));
2733 BOOST_TEST(! operator==(s1, s2));
2734 BOOST_TEST(! operator==(v1, s2));
2735 BOOST_TEST(! operator==(c1, s2));
2736 BOOST_TEST( operator!=(s1, s2));
2737 BOOST_TEST( operator!=(v1, s2));
2738 BOOST_TEST( operator!=(c1, s2));
2739 BOOST_TEST( operator>=(s1, s2));
2740 BOOST_TEST( operator>=(v1, s2));
2741 BOOST_TEST( operator>=(c1, s2));
2742 BOOST_TEST( operator> (s1, s2));
2743 BOOST_TEST( operator> (v1, s2));
2744 BOOST_TEST( operator> (c1, s2));
2745 }
2746
2747 void
2748 testHash()
2749 {
2750 // libstdc++ 4.8 bug
2751 #if !defined(__GNUC__) || (__GNUC__ > 4 || \
2752 (__GNUC__ == 4 && __GNUC_MINOR__ > 8))
2753 {
2754 std::unordered_set<string> us;
2755 us.emplace("first");
2756 us.emplace("second");
2757 }
2758 {
2759 std::unordered_set<string>(
2760 0,
2761 std::hash<string>(32));
2762 }
2763 #endif
2764 {
2765 std::hash<string> h1(32);
2766 std::hash<string> h2(h1);
2767 std::hash<string> h3(59);
2768 h1 = h3;
2769 h2 = h3;
2770 (void)h2;
2771 }
2772 }
2773
2774 void
2775 run()
2776 {
2777 testConstruction();
2778 testAssignment();
2779 testAssign();
2780 testConversion();
2781 testElementAccess();
2782 testIterators();
2783 testCapacity();
2784
2785 testClear();
2786 testInsert();
2787 testErase();
2788 testPushPop();
2789 testAppend();
2790 testPlusEquals();
2791 testCompare();
2792 testStartEndsWith();
2793 testReplace();
2794 testSubStr();
2795 testCopy();
2796 testResize();
2797 testSwap();
2798
2799 testFind();
2800 testRfind();
2801 testFindFirstOf();
2802 testFindFirstNotOf();
2803 testFindLastOf();
2804 testFindLastNotOf();
2805
2806 testNonMembers();
2807
2808 testHash();
2809 }
2810 };
2811
2812 TEST_SUITE(string_test, "boost.json.string");
2813
2814 BOOST_JSON_NS_END