1 /*
2 * Copyright (c) 2016, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
8 */
9
10 #include <fatal/string/rope.h>
11
12 #include <fatal/test/driver.h>
13
14 #include <fatal/math/numerics.h>
15 #include <fatal/utility/timed_iterations.h>
16
17 #include <sstream>
18 #include <string>
19 #include <utility>
20
21 namespace fatal {
22
23 #define TEST_IMPL_SINGLE_STRING(Fn) \
24 Fn(""); \
25 Fn('1'); \
26 Fn("1"); \
27 Fn(std::string("1")); \
28 Fn("12"); \
29 Fn(std::string("12")); \
30 Fn("123"); \
31 Fn(std::string("123")); \
32 Fn("hello, world! with some extra strings"); \
33 Fn(std::string("hello, world! with some extra strings")); \
34 Fn( \
35 std::string("hello"), ", ", std::string("world"), '!', " with", \
36 ' ', std::string("some"), " extra", " ", 's', std::string("trings") \
37 ) \
38
39 //////////////////
40 // sanity_check //
41 //////////////////
42
FATAL_TEST(sanity_check,sanity_check)43 FATAL_TEST(sanity_check, sanity_check) {
44 std::string const world("world");
45 std::string extra(" extra");
46
47 rope<> s(
48 std::string("hello"), ", ", world, '!',
49 " with", ' ', std::string("some"), extra, " ", 's', std::string("trings")
50 );
51
52 std::string const expected("hello, world! with some extra strings");
53
54 FATAL_EXPECT_EQ(expected, s);
55
56 auto const r = s.to_string();
57 FATAL_EXPECT_EQ(expected, r);
58
59 std::ostringstream ss;
60 ss << s;
61 FATAL_EXPECT_EQ(expected, ss.str());
62
63 rope<> unitary;
64 unitary.append(expected);
65
66 auto const u = unitary.to_string();
67
68 FATAL_EXPECT_EQ(expected, u);
69 FATAL_EXPECT_EQ(r, u);
70
71 FATAL_EXPECT_EQ(expected, unitary);
72 FATAL_EXPECT_EQ(s, unitary);
73 FATAL_EXPECT_EQ(unitary, s);
74
75 rope<>::hasher hasher;
76
77 auto const hr1 = hasher(s);
78 auto const hu1 = hasher(unitary);
79 auto const hr2 = rope<>::hasher()(s);
80 auto const hu2 = rope<>::hasher()(unitary);
81
82 FATAL_EXPECT_EQ(hr1, hr2);
83 FATAL_EXPECT_EQ(hu1, hu2);
84
85 FATAL_EXPECT_EQ(hr1, hu1);
86 }
87
88 //////////
89 // size //
90 //////////
91
FATAL_TEST(sanity_check,size)92 FATAL_TEST(sanity_check, size) {
93 rope<> r;
94 FATAL_EXPECT_EQ(0, r.size());
95
96 r.push_back('0');
97 FATAL_EXPECT_EQ(1, r.size());
98
99 r.append("12");
100 FATAL_EXPECT_EQ(3, r.size());
101
102 r.append(std::string("456"));
103 FATAL_EXPECT_EQ(6, r.size());
104
105 r.clear();
106 FATAL_EXPECT_EQ(0, r.size());
107 }
108
109 ///////////
110 // empty //
111 ///////////
112
FATAL_TEST(sanity_check,empty)113 FATAL_TEST(sanity_check, empty) {
114 rope<> r;
115 FATAL_EXPECT_TRUE(r.empty());
116
117 r.push_back('0');
118 FATAL_EXPECT_FALSE(r.empty());
119
120 r.clear();
121 FATAL_EXPECT_TRUE(r.empty());
122
123 r.append("12");
124 FATAL_EXPECT_FALSE(r.empty());
125
126 r.clear();
127 FATAL_EXPECT_TRUE(r.empty());
128
129 r.append(std::string("456"));
130 FATAL_EXPECT_FALSE(r.empty());
131
132 r.clear();
133 FATAL_EXPECT_TRUE(r.empty());
134 }
135
136 ////////////////
137 // comparison //
138 ////////////////
139
FATAL_TEST(comparison,equal)140 FATAL_TEST(comparison, equal) {
141 # define TEST_IMPL_COMPARE(r, other) \
142 do { \
143 FATAL_EXPECT_EQ(0, r.compare(other)); \
144 \
145 FATAL_EXPECT_TRUE(r == other); \
146 FATAL_EXPECT_TRUE(other == r); \
147 \
148 FATAL_EXPECT_FALSE(r != other); \
149 FATAL_EXPECT_FALSE(other != r); \
150 \
151 FATAL_EXPECT_FALSE(r < other); \
152 FATAL_EXPECT_FALSE(other < r); \
153 \
154 FATAL_EXPECT_TRUE(r <= other); \
155 FATAL_EXPECT_TRUE(other <= r); \
156 \
157 FATAL_EXPECT_FALSE(r > other); \
158 FATAL_EXPECT_FALSE(other > r); \
159 \
160 FATAL_EXPECT_TRUE(r >= other); \
161 FATAL_EXPECT_TRUE(other >= r); \
162 } while (false)
163
164 # define TEST_IMPL(...) \
165 do { \
166 auto const str = to_string(__VA_ARGS__); \
167 \
168 { \
169 rope<> r1(__VA_ARGS__); \
170 auto cr1 = r1.mimic(); \
171 rope<> r2(__VA_ARGS__); \
172 auto cr2 = r2.mimic(); \
173 string_view ref(str); \
174 auto cstr = str.c_str(); \
175 std::vector<char> v(str.cbegin(), str.cend()); \
176 v.push_back('\0'); \
177 auto c = v.data(); \
178 std::string s(str); \
179 \
180 TEST_IMPL_COMPARE(r1, r1); \
181 TEST_IMPL_COMPARE(cr1, r1); \
182 TEST_IMPL_COMPARE(r1, cr1); \
183 TEST_IMPL_COMPARE(r1, r2); \
184 TEST_IMPL_COMPARE(cr1, r2); \
185 TEST_IMPL_COMPARE(r1, cr2); \
186 TEST_IMPL_COMPARE(r1, ref); \
187 TEST_IMPL_COMPARE(r1, cstr); \
188 TEST_IMPL_COMPARE(r1, c); \
189 TEST_IMPL_COMPARE(r1, s); \
190 TEST_IMPL_COMPARE(cr1, ref); \
191 TEST_IMPL_COMPARE(cr1, cstr); \
192 TEST_IMPL_COMPARE(cr1, c); \
193 TEST_IMPL_COMPARE(cr1, s); \
194 } \
195 { \
196 rope<> const r1(__VA_ARGS__); \
197 auto const cr1 = r1.mimic(); \
198 rope<> const r2(__VA_ARGS__); \
199 auto const cr2 = r2.mimic(); \
200 string_view const ref(str); \
201 auto const cstr = str.c_str(); \
202 std::vector<char> v(str.cbegin(), str.cend()); \
203 v.push_back('\0'); \
204 auto const c = v.data(); \
205 std::string const s(str); \
206 \
207 TEST_IMPL_COMPARE(r1, r1); \
208 TEST_IMPL_COMPARE(cr1, r1); \
209 TEST_IMPL_COMPARE(r1, cr1); \
210 TEST_IMPL_COMPARE(r1, r2); \
211 TEST_IMPL_COMPARE(cr1, r2); \
212 TEST_IMPL_COMPARE(r1, cr2); \
213 TEST_IMPL_COMPARE(r1, ref); \
214 TEST_IMPL_COMPARE(r1, cstr); \
215 TEST_IMPL_COMPARE(r1, c); \
216 TEST_IMPL_COMPARE(r1, s); \
217 TEST_IMPL_COMPARE(cr1, ref); \
218 TEST_IMPL_COMPARE(cr1, cstr); \
219 TEST_IMPL_COMPARE(cr1, c); \
220 TEST_IMPL_COMPARE(cr1, s); \
221 } \
222 { \
223 rope<> r1(__VA_ARGS__); \
224 auto cr1 = r1.mimic(); \
225 rope<> r2(__VA_ARGS__); \
226 auto cr2 = r2.mimic(); \
227 string_view ref(str); \
228 auto cstr = str.c_str(); \
229 std::vector<char> v(str.cbegin(), str.cend()); \
230 v.push_back('\0'); \
231 auto c = v.data(); \
232 std::string s(str); \
233 \
234 TEST_IMPL_COMPARE(std::move(r1), std::move(r1)); \
235 TEST_IMPL_COMPARE(std::move(cr1), std::move(r1)); \
236 TEST_IMPL_COMPARE(std::move(r1), std::move(cr1)); \
237 TEST_IMPL_COMPARE(std::move(r1), std::move(r2)); \
238 TEST_IMPL_COMPARE(std::move(cr1), std::move(r2)); \
239 TEST_IMPL_COMPARE(std::move(r1), std::move(cr2)); \
240 TEST_IMPL_COMPARE(std::move(r1), std::move(ref)); \
241 TEST_IMPL_COMPARE(std::move(r1), std::move(cstr)); \
242 TEST_IMPL_COMPARE(std::move(r1), std::move(c)); \
243 TEST_IMPL_COMPARE(std::move(r1), std::move(s)); \
244 TEST_IMPL_COMPARE(std::move(cr1), std::move(ref)); \
245 TEST_IMPL_COMPARE(std::move(cr1), std::move(cstr)); \
246 TEST_IMPL_COMPARE(std::move(cr1), std::move(c)); \
247 TEST_IMPL_COMPARE(std::move(cr1), std::move(s)); \
248 } \
249 { \
250 rope<> r1(__VA_ARGS__); \
251 auto cr1 = r1.mimic(); \
252 std::vector<char> v(str.cbegin(), str.cend()); \
253 v.push_back('\0'); \
254 \
255 TEST_IMPL_COMPARE(r1, rope<>(__VA_ARGS__)); \
256 TEST_IMPL_COMPARE(cr1, rope<>(__VA_ARGS__)); \
257 TEST_IMPL_COMPARE(r1, rope<>(__VA_ARGS__).mimic()); \
258 TEST_IMPL_COMPARE(cr1, rope<>(__VA_ARGS__).mimic()); \
259 TEST_IMPL_COMPARE(r1, string_view(str)); \
260 TEST_IMPL_COMPARE(r1, str.c_str()); \
261 TEST_IMPL_COMPARE(r1, v.data()); \
262 TEST_IMPL_COMPARE(r1, std::string(str)); \
263 TEST_IMPL_COMPARE(cr1, string_view(str)); \
264 TEST_IMPL_COMPARE(cr1, str.c_str()); \
265 TEST_IMPL_COMPARE(cr1, v.data()); \
266 TEST_IMPL_COMPARE(cr1, std::string(str)); \
267 } \
268 } while (false)
269
270 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
271
272 # undef TEST_IMPL
273 # undef TEST_IMPL_COMPARE
274 }
275
FATAL_TEST(comparison,not_equal)276 FATAL_TEST(comparison, not_equal) {
277 # define TEST_IMPL_COMPARE(r, other, expected_less) \
278 do { \
279 if (expected_less) { \
280 FATAL_EXPECT_LT(r.compare(other), 0); \
281 } else { \
282 FATAL_EXPECT_GT(r.compare(other), 0); \
283 } \
284 \
285 FATAL_EXPECT_FALSE(r == other); \
286 FATAL_EXPECT_FALSE(other == r); \
287 \
288 FATAL_EXPECT_TRUE(r != other); \
289 FATAL_EXPECT_TRUE(other != r); \
290 \
291 FATAL_EXPECT_EQ(expected_less, r < other); \
292 FATAL_EXPECT_NE(expected_less, other < r); \
293 \
294 FATAL_EXPECT_EQ(expected_less, r <= other); \
295 FATAL_EXPECT_NE(expected_less, other <= r); \
296 \
297 FATAL_EXPECT_NE(expected_less, r > other); \
298 FATAL_EXPECT_EQ(expected_less, other > r); \
299 \
300 FATAL_EXPECT_NE(expected_less, r >= other); \
301 FATAL_EXPECT_EQ(expected_less, other >= r); \
302 } while (false)
303
304 std::vector<rope<>> v;
305 TEST_IMPL_SINGLE_STRING(v.emplace_back);
306
307 for (auto l = v.size(); l--; ) {
308 for (auto r = v.size(); r--; ) {
309 auto ls = v[l].to_string();
310 auto rs = v[r].to_string();
311
312 if (l == r || ls == rs) {
313 continue;
314 }
315
316 // TODO: ADD MIMICS
317 auto test = [](
318 rope<> &lhs,
319 rope<> &rhs,
320 bool expected_less
321 ) {
322 auto const lstr = lhs.to_string();
323 auto const rstr = rhs.to_string();
324 {
325 auto &r1 = lhs;
326 auto &r2 = rhs;
327 string_view ref(rstr);
328 auto cstr = rstr.c_str();
329 std::vector<char> vc(rstr.cbegin(), rstr.cend());
330 vc.push_back('\0');
331 auto c = vc.data();
332 std::string s(rstr);
333
334 TEST_IMPL_COMPARE(r1, r2, expected_less);
335 TEST_IMPL_COMPARE(r1, ref, expected_less);
336 TEST_IMPL_COMPARE(r1, cstr, expected_less);
337 TEST_IMPL_COMPARE(r1, c, expected_less);
338 TEST_IMPL_COMPARE(r1, s, expected_less);
339 }
340 {
341 auto const &r1 = lhs;
342 auto const &r2 = rhs;
343 string_view const ref(rstr);
344 auto const cstr = rstr.c_str();
345 std::vector<char> vc(rstr.cbegin(), rstr.cend());
346 vc.push_back('\0');
347 auto const c = vc.data();
348 std::string const s(rstr);
349
350 TEST_IMPL_COMPARE(r1, r2, expected_less);
351 TEST_IMPL_COMPARE(r1, ref, expected_less);
352 TEST_IMPL_COMPARE(r1, cstr, expected_less);
353 TEST_IMPL_COMPARE(r1, c, expected_less);
354 TEST_IMPL_COMPARE(r1, s, expected_less);
355 }
356 {
357 auto &r1 = lhs;
358 auto &r2 = rhs;
359 string_view ref(rstr);
360 auto cstr = rstr.c_str();
361 std::vector<char> vc(rstr.cbegin(), rstr.cend());
362 vc.push_back('\0');
363 auto c = vc.data();
364 std::string s(rstr);
365
366 TEST_IMPL_COMPARE(std::move(r1), std::move(r2), expected_less);
367 TEST_IMPL_COMPARE(std::move(r1), std::move(ref), expected_less);
368 TEST_IMPL_COMPARE(std::move(r1), std::move(cstr), expected_less);
369 TEST_IMPL_COMPARE(std::move(r1), std::move(c), expected_less);
370 TEST_IMPL_COMPARE(std::move(r1), std::move(s), expected_less);
371 }
372 {
373 auto &r1 = lhs;
374 std::vector<char> vc(rstr.cbegin(), rstr.cend());
375 vc.push_back('\0');
376
377 TEST_IMPL_COMPARE(r1, string_view(rstr), expected_less);
378 TEST_IMPL_COMPARE(r1, rstr.c_str(), expected_less);
379 TEST_IMPL_COMPARE(r1, vc.data(), expected_less);
380 TEST_IMPL_COMPARE(r1, std::string(rstr), expected_less);
381 }
382
383 FATAL_ASSERT_EQ(lhs, lstr);
384 FATAL_ASSERT_EQ(rhs, rstr);
385 };
386
387 test(v[l], v[r], ls < rs);
388 test(v[r], v[l], rs < ls);
389 }
390 }
391
392 # undef TEST_IMPL_COMPARE
393 }
394
395 ///////////////
396 // push_back //
397 ///////////////
398
FATAL_TEST(push_back,char)399 FATAL_TEST(push_back, char) {
400 rope<> r;
401 FATAL_EXPECT_TRUE(r.empty());
402 FATAL_EXPECT_EQ("", r);
403
404 r.push_back('1');
405 FATAL_EXPECT_FALSE(r.empty());
406 FATAL_EXPECT_EQ("1", r);
407
408 char space = ' ';
409 r.push_back(space);
410 FATAL_EXPECT_FALSE(r.empty());
411 FATAL_EXPECT_EQ("1 ", r);
412
413 char two = '2';
414 r.push_back(std::move(two));
415 FATAL_EXPECT_FALSE(r.empty());
416 FATAL_EXPECT_EQ("1 2", r);
417
418 r.push_back(char(' '));
419 FATAL_EXPECT_FALSE(r.empty());
420 FATAL_EXPECT_EQ("1 2 ", r);
421
422 char const three = '3';
423 r.push_back(three);
424 FATAL_EXPECT_FALSE(r.empty());
425 FATAL_EXPECT_EQ("1 2 3", r);
426
427 auto end = "!";
428 r.push_back(end[0]);
429 FATAL_EXPECT_FALSE(r.empty());
430 FATAL_EXPECT_EQ("1 2 3!", r);
431 }
432
433 ////////////
434 // append //
435 ////////////
436
FATAL_TEST(append,append)437 FATAL_TEST(append, append) {
438 rope<> r;
439 FATAL_EXPECT_TRUE(r.empty());
440 FATAL_EXPECT_EQ("", r);
441 FATAL_EXPECT_EQ(0, r.pieces());
442
443 r.append("");
444 FATAL_EXPECT_TRUE(r.empty());
445 FATAL_EXPECT_EQ("", r);
446 FATAL_EXPECT_EQ(0, r.pieces());
447
448 r.append("one");
449 FATAL_EXPECT_FALSE(r.empty());
450 FATAL_EXPECT_EQ("one", r);
451 FATAL_EXPECT_EQ(1, r.pieces());
452
453 r.append(' ');
454 FATAL_EXPECT_FALSE(r.empty());
455 FATAL_EXPECT_EQ("one ", r);
456 FATAL_EXPECT_EQ(2, r.pieces());
457
458 r.append(std::string("two"));
459 FATAL_EXPECT_FALSE(r.empty());
460 FATAL_EXPECT_EQ("one two", r);
461 FATAL_EXPECT_EQ(3, r.pieces());
462
463 r.append(string_view(" "));
464 FATAL_EXPECT_FALSE(r.empty());
465 FATAL_EXPECT_EQ("one two ", r);
466 FATAL_EXPECT_EQ(4, r.pieces());
467
468 std::string three("three");
469 r.append(three);
470 FATAL_EXPECT_FALSE(r.empty());
471 FATAL_EXPECT_EQ("one two three", r);
472 FATAL_EXPECT_EQ(5, r.pieces());
473
474 std::string f(" f");
475 r.append(std::move(f));
476 FATAL_EXPECT_FALSE(r.empty());
477 FATAL_EXPECT_EQ("one two three f", r);
478 FATAL_EXPECT_EQ(6, r.pieces());
479
480 std::string const o("o");
481 r.append(o);
482 FATAL_EXPECT_FALSE(r.empty());
483 FATAL_EXPECT_EQ("one two three fo", r);
484 FATAL_EXPECT_EQ(7, r.pieces());
485
486 string_view const ur("ur");
487 r.append(ur);
488 FATAL_EXPECT_FALSE(r.empty());
489 FATAL_EXPECT_EQ("one two three four", r);
490 FATAL_EXPECT_EQ(8, r.pieces());
491
492 string_view end("!");
493 r.append(end);
494 FATAL_EXPECT_FALSE(r.empty());
495 FATAL_EXPECT_EQ("one two three four!", r);
496 FATAL_EXPECT_EQ(9, r.pieces());
497 }
498
499 //////////////////
500 // multi_append //
501 //////////////////
502
FATAL_TEST(multi_append,none)503 FATAL_TEST(multi_append, none) {
504 rope<> r;
505
506 FATAL_EXPECT_TRUE(r.empty());
507 FATAL_EXPECT_EQ("", r);
508 FATAL_EXPECT_EQ(0, r.pieces());
509
510 r.multi_append();
511 FATAL_EXPECT_TRUE(r.empty());
512 FATAL_EXPECT_EQ("", r);
513 FATAL_EXPECT_EQ(0, r.pieces());
514
515 r.multi_append("");
516 FATAL_EXPECT_TRUE(r.empty());
517 FATAL_EXPECT_EQ("", r);
518 FATAL_EXPECT_EQ(0, r.pieces());
519 }
520
FATAL_TEST(multi_append,one)521 FATAL_TEST(multi_append, one) {
522 rope<> r;
523 FATAL_EXPECT_TRUE(r.empty());
524 FATAL_EXPECT_EQ("", r);
525 FATAL_EXPECT_EQ(0, r.pieces());
526
527 r.multi_append("one");
528 FATAL_EXPECT_FALSE(r.empty());
529 FATAL_EXPECT_EQ("one", r);
530 FATAL_EXPECT_EQ(1, r.pieces());
531
532 r.multi_append(' ');
533 FATAL_EXPECT_FALSE(r.empty());
534 FATAL_EXPECT_EQ("one ", r);
535 FATAL_EXPECT_EQ(2, r.pieces());
536
537 r.multi_append(std::string("two"));
538 FATAL_EXPECT_FALSE(r.empty());
539 FATAL_EXPECT_EQ("one two", r);
540 FATAL_EXPECT_EQ(3, r.pieces());
541
542 r.multi_append(string_view(" "));
543 FATAL_EXPECT_FALSE(r.empty());
544 FATAL_EXPECT_EQ("one two ", r);
545 FATAL_EXPECT_EQ(4, r.pieces());
546
547 std::string three("three");
548 r.multi_append(three);
549 FATAL_EXPECT_FALSE(r.empty());
550 FATAL_EXPECT_EQ("one two three", r);
551 FATAL_EXPECT_EQ(5, r.pieces());
552
553 std::string f(" f");
554 r.multi_append(std::move(f));
555 FATAL_EXPECT_FALSE(r.empty());
556 FATAL_EXPECT_EQ("one two three f", r);
557 FATAL_EXPECT_EQ(6, r.pieces());
558
559 std::string const o("o");
560 r.multi_append(o);
561 FATAL_EXPECT_FALSE(r.empty());
562 FATAL_EXPECT_EQ("one two three fo", r);
563 FATAL_EXPECT_EQ(7, r.pieces());
564
565 string_view const ur("ur");
566 r.multi_append(ur);
567 FATAL_EXPECT_FALSE(r.empty());
568 FATAL_EXPECT_EQ("one two three four", r);
569 FATAL_EXPECT_EQ(8, r.pieces());
570
571 string_view end("!");
572 r.multi_append(end);
573 FATAL_EXPECT_FALSE(r.empty());
574 FATAL_EXPECT_EQ("one two three four!", r);
575 FATAL_EXPECT_EQ(9, r.pieces());
576 }
577
FATAL_TEST(multi_append,two)578 FATAL_TEST(multi_append, two) {
579 rope<> r;
580 FATAL_EXPECT_TRUE(r.empty());
581 FATAL_EXPECT_EQ("", r);
582 FATAL_EXPECT_EQ(0, r.pieces());
583
584 r.multi_append("one", ' ');
585 FATAL_EXPECT_FALSE(r.empty());
586 FATAL_EXPECT_EQ("one ", r);
587 FATAL_EXPECT_EQ(2, r.pieces());
588
589 r.multi_append(std::string("two"), string_view(" "));
590 FATAL_EXPECT_FALSE(r.empty());
591 FATAL_EXPECT_EQ("one two ", r);
592 FATAL_EXPECT_EQ(4, r.pieces());
593
594 std::string three("three");
595 string_view space(" ");
596 r.multi_append(three, space);
597 FATAL_EXPECT_FALSE(r.empty());
598 FATAL_EXPECT_EQ("one two three ", r);
599 FATAL_EXPECT_EQ(6, r.pieces());
600
601 std::string f("f");
602 std::string const o("o");
603 r.multi_append(std::move(f), o);
604 FATAL_EXPECT_FALSE(r.empty());
605 FATAL_EXPECT_EQ("one two three fo", r);
606 FATAL_EXPECT_EQ(8, r.pieces());
607
608 string_view const ur("ur");
609 string_view end("!");
610 r.multi_append(ur, end);
611 FATAL_EXPECT_FALSE(r.empty());
612 FATAL_EXPECT_EQ("one two three four!", r);
613 FATAL_EXPECT_EQ(10, r.pieces());
614 }
615
FATAL_TEST(multi_append,three)616 FATAL_TEST(multi_append, three) {
617 rope<> r;
618 FATAL_EXPECT_TRUE(r.empty());
619 FATAL_EXPECT_EQ("", r);
620 FATAL_EXPECT_EQ(0, r.pieces());
621
622 r.multi_append("one", ' ', std::string("two"));
623 FATAL_EXPECT_FALSE(r.empty());
624 FATAL_EXPECT_EQ("one two", r);
625 FATAL_EXPECT_EQ(3, r.pieces());
626
627 std::string three("three");
628 std::string f(" f");
629
630 r.multi_append(string_view(" "), three, std::move(f));
631 FATAL_EXPECT_FALSE(r.empty());
632 FATAL_EXPECT_EQ("one two three f", r);
633 FATAL_EXPECT_EQ(6, r.pieces());
634
635 std::string const o("o");
636 string_view const ur("ur");
637 string_view end("!");
638
639 r.multi_append(o, ur, end);
640 FATAL_EXPECT_FALSE(r.empty());
641 FATAL_EXPECT_EQ("one two three four!", r);
642 FATAL_EXPECT_EQ(9, r.pieces());
643 }
644
FATAL_TEST(multi_append,many)645 FATAL_TEST(multi_append, many) {
646 rope<> r;
647 FATAL_EXPECT_TRUE(r.empty());
648 FATAL_EXPECT_EQ("", r);
649 FATAL_EXPECT_EQ(0, r.pieces());
650
651 r.multi_append("one", ' ', std::string("two"), string_view(" "));
652 FATAL_EXPECT_FALSE(r.empty());
653 FATAL_EXPECT_EQ("one two ", r);
654 FATAL_EXPECT_EQ(4, r.pieces());
655
656 std::string three("three");
657 std::string const ou("ou");
658 string_view end("!");
659
660 r.multi_append(three, " ", 'f', ou, std::string("r"), end);
661 FATAL_EXPECT_FALSE(r.empty());
662 FATAL_EXPECT_EQ("one two three four!", r);
663 FATAL_EXPECT_EQ(10, r.pieces());
664 }
665
666 ////////////
667 // concat //
668 ////////////
669
FATAL_TEST(concat,empty)670 FATAL_TEST(concat, empty) {
671 rope<> r;
672 FATAL_EXPECT_TRUE(r.empty());
673
674 rope<> other;
675 r.concat(other);
676 FATAL_EXPECT_TRUE(r.empty());
677
678 r.concat(rope<>());
679 FATAL_EXPECT_TRUE(r.empty());
680
681 r.concat(r);
682 FATAL_EXPECT_TRUE(r.empty());
683 }
684
FATAL_TEST(concat,one_piece)685 FATAL_TEST(concat, one_piece) {
686 rope<> r;
687 FATAL_EXPECT_TRUE(r.empty());
688
689 std::string const s1("hello");
690 rope<> r1((std::string(s1)));
691 FATAL_EXPECT_FALSE(r1.empty());
692 r.concat(std::move(r1));
693 FATAL_EXPECT_TRUE(r1.empty());
694 FATAL_EXPECT_EQ(s1, r.to_string());
695 FATAL_EXPECT_EQ(s1, r);
696
697 std::string const s2(", ");
698 rope<> r2(s2);
699 r.concat(r2);
700 FATAL_EXPECT_EQ(s1 + s2, r.to_string());
701 FATAL_EXPECT_EQ(s1 + s2, r);
702
703 std::string const s3("world");
704 r.concat(rope<>(s3));
705 FATAL_EXPECT_EQ(s1 + s2 + s3, r.to_string());
706 FATAL_EXPECT_EQ(s1 + s2 + s3, r);
707
708 std::string const s4("!");
709 rope<> const r4(s4);
710 r.concat(r4);
711 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4, r.to_string());
712 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4, r);
713
714 std::string const s5(" test");
715 rope<> const r5(s5);
716 r.concat(r5);
717 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5, r.to_string());
718 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5, r);
719
720 std::string const s6(" string");
721 rope<> const r6(s6);
722 r.concat(r6);
723 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5 + s6, r.to_string());
724 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5 + s6, r);
725
726 r.concat(r);
727 FATAL_EXPECT_EQ(
728 s1 + s2 + s3 + s4 + s5 + s6
729 + s1 + s2 + s3 + s4 + s5 + s6,
730 r.to_string()
731 );
732 FATAL_EXPECT_EQ(
733 s1 + s2 + s3 + s4 + s5 + s6
734 + s1 + s2 + s3 + s4 + s5 + s6,
735 r
736 );
737
738 FATAL_EXPECT_THROW(std::invalid_argument) { r.concat(std::move(r)); };
739 }
740
FATAL_TEST(concat,two_pieces)741 FATAL_TEST(concat, two_pieces) {
742 rope<> r;
743 FATAL_EXPECT_TRUE(r.empty());
744
745 std::string const s1("hello");
746 std::string const s2(", ");
747
748 rope<> r1(std::string(s1), s2);
749 FATAL_EXPECT_FALSE(r1.empty());
750 r.concat(std::move(r1));
751 FATAL_EXPECT_TRUE(r1.empty());
752 FATAL_EXPECT_EQ(s1 + s2, r.to_string());
753 FATAL_EXPECT_EQ(s1 + s2, r);
754
755 std::string const s3("world");
756 std::string const s4("!");
757
758 rope<> const r2(s3, s4);
759 r.concat(r2);
760 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4, r.to_string());
761 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4, r);
762
763 std::string const s5(" test");
764 std::string const s6(" string");
765
766 rope<> const r3(s5, s6);
767 r.concat(r3);
768 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5 + s6, r.to_string());
769 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5 + s6, r);
770
771 r.concat(r);
772 FATAL_EXPECT_EQ(
773 s1 + s2 + s3 + s4 + s5 + s6
774 + s1 + s2 + s3 + s4 + s5 + s6,
775 r.to_string()
776 );
777 FATAL_EXPECT_EQ(
778 s1 + s2 + s3 + s4 + s5 + s6
779 + s1 + s2 + s3 + s4 + s5 + s6,
780 r
781 );
782
783 FATAL_EXPECT_THROW(std::invalid_argument) { r.concat(std::move(r)); };
784 }
785
FATAL_TEST(concat,three_pieces)786 FATAL_TEST(concat, three_pieces) {
787 rope<> r;
788 FATAL_EXPECT_TRUE(r.empty());
789
790 std::string const s1("hello");
791 std::string const s2(", ");
792 std::string const s3("world");
793
794 rope<> r1(std::string(s1), s2, s3);
795 FATAL_EXPECT_FALSE(r1.empty());
796 r.concat(std::move(r1));
797 FATAL_EXPECT_TRUE(r1.empty());
798 FATAL_EXPECT_EQ(s1 + s2 + s3, r.to_string());
799 FATAL_EXPECT_EQ(s1 + s2 + s3, r);
800
801 std::string const s4("!");
802 std::string const s5(" test");
803 std::string const s6(" string");
804
805 rope<> const r2(s4, s5, s6);
806 r.concat(r2);
807 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5 + s6, r.to_string());
808 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5 + s6, r);
809
810 r.concat(r);
811 FATAL_EXPECT_EQ(
812 s1 + s2 + s3 + s4 + s5 + s6
813 + s1 + s2 + s3 + s4 + s5 + s6,
814 r.to_string()
815 );
816 FATAL_EXPECT_EQ(
817 s1 + s2 + s3 + s4 + s5 + s6
818 + s1 + s2 + s3 + s4 + s5 + s6,
819 r
820 );
821
822 FATAL_EXPECT_THROW(std::invalid_argument) { r.concat(std::move(r)); };
823 }
824
FATAL_TEST(concat,many_pieces)825 FATAL_TEST(concat, many_pieces) {
826 rope<> r;
827 FATAL_EXPECT_TRUE(r.empty());
828
829 std::string const s1("hello");
830 std::string const s2(", ");
831 std::string const s3("world");
832 std::string const s4("!");
833 std::string const s5(" test");
834 std::string const s6(" string");
835
836 rope<> r1(std::string(s1), s2, s3, s4, s5, s6);
837 FATAL_EXPECT_FALSE(r1.empty());
838 r.concat(std::move(r1));
839 FATAL_EXPECT_TRUE(r1.empty());
840 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5 + s6, r.to_string());
841 FATAL_EXPECT_EQ(s1 + s2 + s3 + s4 + s5 + s6, r);
842
843 rope<> r2(std::string(s1), s2, s3, s4, s5, s6);
844 r.concat(r2);
845 FATAL_EXPECT_EQ(
846 s1 + s2 + s3 + s4 + s5 + s6
847 + s1 + s2 + s3 + s4 + s5 + s6,
848 r.to_string()
849 );
850 FATAL_EXPECT_EQ(
851 s1 + s2 + s3 + s4 + s5 + s6
852 + s1 + s2 + s3 + s4 + s5 + s6,
853 r
854 );
855
856 r.concat(r);
857 FATAL_EXPECT_EQ(
858 s1 + s2 + s3 + s4 + s5 + s6
859 + s1 + s2 + s3 + s4 + s5 + s6
860 + s1 + s2 + s3 + s4 + s5 + s6
861 + s1 + s2 + s3 + s4 + s5 + s6,
862 r.to_string()
863 );
864 FATAL_EXPECT_EQ(
865 s1 + s2 + s3 + s4 + s5 + s6
866 + s1 + s2 + s3 + s4 + s5 + s6
867 + s1 + s2 + s3 + s4 + s5 + s6
868 + s1 + s2 + s3 + s4 + s5 + s6,
869 r
870 );
871
872 FATAL_EXPECT_THROW(std::invalid_argument) { r.concat(std::move(r)); };
873 }
874
875 ///////////////
876 // accessors //
877 ///////////////
878
FATAL_TEST(accessors,front_back)879 FATAL_TEST(accessors, front_back) {
880 rope<> r;
881
882 r.append('a');
883 FATAL_EXPECT_EQ('a', r.front());
884 FATAL_EXPECT_EQ('a', r.back());
885
886 r.append("_b_c_d_e");
887 FATAL_EXPECT_EQ('a', r.front());
888 FATAL_EXPECT_EQ('e', r.back());
889
890 std::string f_g_h_i("_f_g_h_i");
891 r.append(f_g_h_i);
892 FATAL_EXPECT_EQ('a', r.front());
893 FATAL_EXPECT_EQ('i', r.back());
894
895 char const underscore = '_';
896 r.append(underscore);
897 FATAL_EXPECT_EQ('a', r.front());
898 FATAL_EXPECT_EQ('_', r.back());
899
900 r.append(std::string("j_k_l_m"));
901 FATAL_EXPECT_EQ('a', r.front());
902 FATAL_EXPECT_EQ('m', r.back());
903 }
904
905 //////////////////////
906 // at / operator [] //
907 //////////////////////
908
FATAL_TEST(accessors,at)909 FATAL_TEST(accessors, at) {
910 rope<> r;
911 FATAL_EXPECT_THROW(std::out_of_range) { r.at(0); };
912 FATAL_EXPECT_THROW(std::out_of_range) { r.at(2); };
913 FATAL_EXPECT_THROW(std::out_of_range) { r.at(4); };
914 FATAL_EXPECT_THROW(std::out_of_range) { r.at(14); };
915 FATAL_EXPECT_THROW(std::out_of_range) { r.at(17); };
916 FATAL_EXPECT_THROW(std::out_of_range) { r.at(18); };
917 FATAL_EXPECT_THROW(std::out_of_range) { r.at(r.size() - 1); };
918 FATAL_EXPECT_THROW(std::out_of_range) { r.at(r.size()); };
919
920 r.append('a');
921 FATAL_EXPECT_EQ('a', r.at(0));
922 FATAL_EXPECT_THROW(std::out_of_range) { r.at(2); };
923 FATAL_EXPECT_THROW(std::out_of_range) { r.at(4); };
924 FATAL_EXPECT_THROW(std::out_of_range) { r.at(14); };
925 FATAL_EXPECT_THROW(std::out_of_range) { r.at(17); };
926 FATAL_EXPECT_THROW(std::out_of_range) { r.at(18); };
927 FATAL_EXPECT_EQ('a', r.at(r.size() - 1));
928 FATAL_EXPECT_THROW(std::out_of_range) { r.at(r.size()); };
929
930 r.append("_b_c_d_e");
931 FATAL_EXPECT_EQ('a', r.at(0));
932 FATAL_EXPECT_EQ('b', r.at(2));
933 FATAL_EXPECT_EQ('c', r.at(4));
934 FATAL_EXPECT_THROW(std::out_of_range) { r.at(14); };
935 FATAL_EXPECT_THROW(std::out_of_range) { r.at(17); };
936 FATAL_EXPECT_THROW(std::out_of_range) { r.at(18); };
937 FATAL_EXPECT_EQ('e', r.at(r.size() - 1));
938 FATAL_EXPECT_THROW(std::out_of_range) { r.at(r.size()); };
939
940 std::string f_g_h_i("_f_g_h_i");
941 r.append(f_g_h_i);
942 FATAL_EXPECT_EQ('a', r.at(0));
943 FATAL_EXPECT_EQ('b', r.at(2));
944 FATAL_EXPECT_EQ('c', r.at(4));
945 FATAL_EXPECT_EQ('h', r.at(14));
946 FATAL_EXPECT_THROW(std::out_of_range) { r.at(17); };
947 FATAL_EXPECT_THROW(std::out_of_range) { r.at(18); };
948 FATAL_EXPECT_EQ('i', r.at(r.size() - 1));
949 FATAL_EXPECT_THROW(std::out_of_range) { r.at(r.size()); };
950
951 char const underscore = '_';
952 r.append(underscore);
953 FATAL_EXPECT_EQ('a', r.at(0));
954 FATAL_EXPECT_EQ('b', r.at(2));
955 FATAL_EXPECT_EQ('c', r.at(4));
956 FATAL_EXPECT_EQ('h', r.at(14));
957 FATAL_EXPECT_EQ('_', r.at(17));
958 FATAL_EXPECT_THROW(std::out_of_range) { r.at(18); };
959 FATAL_EXPECT_EQ('_', r.at(r.size() - 1));
960 FATAL_EXPECT_THROW(std::out_of_range) { r.at(r.size()); };
961
962 r.append(std::string("j_k_l_m"));
963 FATAL_EXPECT_EQ('a', r.at(0));
964 FATAL_EXPECT_EQ('b', r.at(2));
965 FATAL_EXPECT_EQ('c', r.at(4));
966 FATAL_EXPECT_EQ('h', r.at(14));
967 FATAL_EXPECT_EQ('_', r.at(17));
968 FATAL_EXPECT_EQ('j', r.at(18));
969 FATAL_EXPECT_EQ('m', r.at(r.size() - 1));
970 FATAL_EXPECT_THROW(std::out_of_range) { r.at(r.size()); };
971 }
972
FATAL_TEST(accessors,operator[])973 FATAL_TEST(accessors, operator []) {
974 rope<> r;
975
976 r.append('a');
977 FATAL_EXPECT_EQ('a', r[0]);
978 FATAL_EXPECT_EQ('a', r[r.size() - 1]);
979
980 r.append("_b_c_d_e");
981 FATAL_EXPECT_EQ('a', r[0]);
982 FATAL_EXPECT_EQ('b', r[2]);
983 FATAL_EXPECT_EQ('c', r[4]);
984 FATAL_EXPECT_EQ('e', r[r.size() - 1]);
985
986 std::string f_g_h_i("_f_g_h_i");
987 r.append(f_g_h_i);
988 FATAL_EXPECT_EQ('a', r[0]);
989 FATAL_EXPECT_EQ('b', r[2]);
990 FATAL_EXPECT_EQ('c', r[4]);
991 FATAL_EXPECT_EQ('h', r[14]);
992 FATAL_EXPECT_EQ('i', r[r.size() - 1]);
993
994 char const underscore = '_';
995 r.append(underscore);
996 FATAL_EXPECT_EQ('a', r[0]);
997 FATAL_EXPECT_EQ('b', r[2]);
998 FATAL_EXPECT_EQ('c', r[4]);
999 FATAL_EXPECT_EQ('h', r[14]);
1000 FATAL_EXPECT_EQ('_', r[17]);
1001 FATAL_EXPECT_EQ('_', r[r.size() - 1]);
1002
1003 r.append(std::string("j_k_l_m"));
1004 FATAL_EXPECT_EQ('a', r[0]);
1005 FATAL_EXPECT_EQ('b', r[2]);
1006 FATAL_EXPECT_EQ('c', r[4]);
1007 FATAL_EXPECT_EQ('h', r[14]);
1008 FATAL_EXPECT_EQ('_', r[17]);
1009 FATAL_EXPECT_EQ('j', r[18]);
1010 FATAL_EXPECT_EQ('m', r[r.size() - 1]);
1011 }
1012
1013 //////////
1014 // copy //
1015 //////////
1016
1017 // TODO: TEST COPY WITH OFFSET
1018
FATAL_TEST(copy,copy)1019 FATAL_TEST(copy, copy) {
1020 # define TEST_IMPL(...) \
1021 do { \
1022 rope<> r(__VA_ARGS__); \
1023 \
1024 std::vector<char> buffer(r.size()); \
1025 \
1026 auto const end = r.copy( \
1027 buffer.data(), \
1028 std::next(buffer.data(), signed_cast(buffer.size())) \
1029 ); \
1030 \
1031 FATAL_EXPECT_EQ( \
1032 r.size(), \
1033 unsigned_cast(std::distance(buffer.data(), end)) \
1034 ); \
1035 FATAL_EXPECT_EQ( \
1036 buffer.size(), \
1037 unsigned_cast(std::distance(buffer.data(), end)) \
1038 ); \
1039 \
1040 FATAL_EXPECT_EQ(r, buffer); \
1041 } while (false)
1042
1043 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1044
1045 # undef TEST_IMPL
1046 }
1047
1048 ///////////////
1049 // to_string //
1050 ///////////////
1051
FATAL_TEST(string,to_string)1052 FATAL_TEST(string, to_string) {
1053 # define TEST_IMPL(...) \
1054 do { \
1055 rope<> r(__VA_ARGS__); \
1056 FATAL_EXPECT_EQ(to_string(__VA_ARGS__), r.to_string()); \
1057 } while (false)
1058
1059 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1060
1061 # undef TEST_IMPL
1062 }
1063
1064 ///////////////
1065 // append_to //
1066 ///////////////
1067
FATAL_TEST(string,append_to)1068 FATAL_TEST(string, append_to) {
1069 # define TEST_IMPL(...) \
1070 do { \
1071 rope<> r(__VA_ARGS__); \
1072 std::string s; \
1073 FATAL_EXPECT_EQ(to_string(__VA_ARGS__), r.append_to(s)); \
1074 } while (false)
1075
1076 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1077
1078 # undef TEST_IMPL
1079 }
1080
1081 //////////////
1082 // capacity //
1083 //////////////
1084
FATAL_TEST(capacity,empty)1085 FATAL_TEST(capacity, empty) {
1086 # define TEST_IMPL(SmallBufferSize) \
1087 do { \
1088 rope<SmallBufferSize> r; \
1089 FATAL_EXPECT_EQ(SmallBufferSize, r.capacity()); \
1090 for (auto i = SmallBufferSize; i--; ) { \
1091 r.append(' '); \
1092 } \
1093 FATAL_EXPECT_EQ(SmallBufferSize, r.capacity()); \
1094 FATAL_EXPECT_EQ(r.size(), r.capacity()); \
1095 r.append(' '); \
1096 FATAL_EXPECT_NE(SmallBufferSize, r.capacity()); \
1097 } while (false)
1098
1099 TEST_IMPL(0);
1100 TEST_IMPL(1);
1101 TEST_IMPL(2);
1102 TEST_IMPL(3);
1103 TEST_IMPL(4);
1104 TEST_IMPL(5);
1105 TEST_IMPL(6);
1106 TEST_IMPL(7);
1107 TEST_IMPL(8);
1108 TEST_IMPL(9);
1109 TEST_IMPL(10);
1110 TEST_IMPL(11);
1111 TEST_IMPL(12);
1112 TEST_IMPL(13);
1113 TEST_IMPL(14);
1114 TEST_IMPL(15);
1115 TEST_IMPL(16);
1116 TEST_IMPL(17);
1117 TEST_IMPL(18);
1118 TEST_IMPL(19);
1119 TEST_IMPL(20);
1120 TEST_IMPL(21);
1121 TEST_IMPL(22);
1122 TEST_IMPL(23);
1123 TEST_IMPL(24);
1124 TEST_IMPL(25);
1125 TEST_IMPL(26);
1126 TEST_IMPL(27);
1127 TEST_IMPL(28);
1128 TEST_IMPL(29);
1129 TEST_IMPL(30);
1130 TEST_IMPL(31);
1131 TEST_IMPL(32);
1132
1133 # undef TEST_IMPL
1134 }
1135
FATAL_TEST(capacity,reserve (absolute))1136 FATAL_TEST(capacity, reserve (absolute)) {
1137 # define TEST_IMPL(SmallBufferSize) \
1138 do { \
1139 auto const capacity = SmallBufferSize * 2 + 1; \
1140 do { \
1141 rope<SmallBufferSize> r; \
1142 FATAL_EXPECT_EQ(SmallBufferSize, r.capacity()); \
1143 r.reserve(capacity); \
1144 FATAL_EXPECT_EQ(capacity, r.capacity()); \
1145 r.reserve(SmallBufferSize); \
1146 FATAL_EXPECT_EQ(capacity, r.capacity()); \
1147 } while (false); \
1148 do { \
1149 rope<SmallBufferSize> r; \
1150 FATAL_EXPECT_EQ(SmallBufferSize, r.capacity()); \
1151 r.reserve(capacity, false); \
1152 FATAL_EXPECT_EQ(capacity, r.capacity()); \
1153 r.reserve(SmallBufferSize, false); \
1154 FATAL_EXPECT_EQ(capacity, r.capacity()); \
1155 } while (false); \
1156 } while (false)
1157
1158 TEST_IMPL(0);
1159 TEST_IMPL(1);
1160 TEST_IMPL(2);
1161 TEST_IMPL(3);
1162 TEST_IMPL(4);
1163 TEST_IMPL(5);
1164 TEST_IMPL(6);
1165 TEST_IMPL(7);
1166 TEST_IMPL(8);
1167 TEST_IMPL(9);
1168 TEST_IMPL(10);
1169 TEST_IMPL(11);
1170 TEST_IMPL(12);
1171 TEST_IMPL(13);
1172 TEST_IMPL(14);
1173 TEST_IMPL(15);
1174 TEST_IMPL(16);
1175 TEST_IMPL(17);
1176 TEST_IMPL(18);
1177 TEST_IMPL(19);
1178 TEST_IMPL(20);
1179 TEST_IMPL(21);
1180 TEST_IMPL(22);
1181 TEST_IMPL(23);
1182 TEST_IMPL(24);
1183 TEST_IMPL(25);
1184 TEST_IMPL(26);
1185 TEST_IMPL(27);
1186 TEST_IMPL(28);
1187 TEST_IMPL(29);
1188 TEST_IMPL(30);
1189 TEST_IMPL(31);
1190 TEST_IMPL(32);
1191
1192 # undef TEST_IMPL
1193 }
1194
FATAL_TEST(capacity,reserve (relative))1195 FATAL_TEST(capacity, reserve (relative)) {
1196 # define TEST_IMPL(SmallBufferSize) \
1197 do { \
1198 rope<SmallBufferSize> r; \
1199 FATAL_EXPECT_EQ(SmallBufferSize, r.capacity()); \
1200 auto const additional = SmallBufferSize + 1; \
1201 auto const capacity = SmallBufferSize + additional; \
1202 r.reserve(capacity, true); \
1203 FATAL_EXPECT_EQ(capacity, r.capacity()); \
1204 r.reserve(SmallBufferSize, true); \
1205 FATAL_EXPECT_EQ(capacity, r.capacity()); \
1206 r.reserve(additional, true); \
1207 FATAL_EXPECT_EQ(capacity, r.capacity()); \
1208 } while (false)
1209
1210 TEST_IMPL(0);
1211 TEST_IMPL(1);
1212 TEST_IMPL(2);
1213 TEST_IMPL(3);
1214 TEST_IMPL(4);
1215 TEST_IMPL(5);
1216 TEST_IMPL(6);
1217 TEST_IMPL(7);
1218 TEST_IMPL(8);
1219 TEST_IMPL(9);
1220 TEST_IMPL(10);
1221 TEST_IMPL(11);
1222 TEST_IMPL(12);
1223 TEST_IMPL(13);
1224 TEST_IMPL(14);
1225 TEST_IMPL(15);
1226 TEST_IMPL(16);
1227 TEST_IMPL(17);
1228 TEST_IMPL(18);
1229 TEST_IMPL(19);
1230 TEST_IMPL(20);
1231 TEST_IMPL(21);
1232 TEST_IMPL(22);
1233 TEST_IMPL(23);
1234 TEST_IMPL(24);
1235 TEST_IMPL(25);
1236 TEST_IMPL(26);
1237 TEST_IMPL(27);
1238 TEST_IMPL(28);
1239 TEST_IMPL(29);
1240 TEST_IMPL(30);
1241 TEST_IMPL(31);
1242 TEST_IMPL(32);
1243
1244 # undef TEST_IMPL
1245 }
1246
1247 ///////////
1248 // clear //
1249 ///////////
1250
FATAL_TEST(clear,empty)1251 FATAL_TEST(clear, empty) {
1252 rope<> r;
1253 FATAL_EXPECT_TRUE(r.empty());
1254 FATAL_EXPECT_EQ("", r);
1255 FATAL_EXPECT_EQ(0, r.pieces());
1256
1257 r.clear();
1258 FATAL_EXPECT_TRUE(r.empty());
1259 FATAL_EXPECT_EQ("", r);
1260 FATAL_EXPECT_EQ(0, r.pieces());
1261
1262 r.clear();
1263 FATAL_EXPECT_TRUE(r.empty());
1264 FATAL_EXPECT_EQ("", r);
1265 FATAL_EXPECT_EQ(0, r.pieces());
1266
1267 r.clear();
1268 FATAL_EXPECT_TRUE(r.empty());
1269 FATAL_EXPECT_EQ("", r);
1270 FATAL_EXPECT_EQ(0, r.pieces());
1271 }
1272
FATAL_TEST(clear,one)1273 FATAL_TEST(clear, one) {
1274 rope<> r;
1275 FATAL_EXPECT_TRUE(r.empty());
1276 FATAL_EXPECT_EQ("", r);
1277 FATAL_EXPECT_EQ(0, r.pieces());
1278
1279 r.append("one");
1280 FATAL_EXPECT_FALSE(r.empty());
1281 FATAL_EXPECT_EQ("one", r);
1282 FATAL_EXPECT_EQ(1, r.pieces());
1283
1284 r.clear();
1285 FATAL_EXPECT_TRUE(r.empty());
1286 FATAL_EXPECT_EQ("", r);
1287 FATAL_EXPECT_EQ(0, r.pieces());
1288
1289 r.append(' ');
1290 FATAL_EXPECT_FALSE(r.empty());
1291 FATAL_EXPECT_EQ(" ", r);
1292 FATAL_EXPECT_EQ(1, r.pieces());
1293
1294 r.clear();
1295 FATAL_EXPECT_TRUE(r.empty());
1296 FATAL_EXPECT_EQ("", r);
1297 FATAL_EXPECT_EQ(0, r.pieces());
1298
1299 r.append(std::string("two"));
1300 FATAL_EXPECT_FALSE(r.empty());
1301 FATAL_EXPECT_EQ("two", r);
1302 FATAL_EXPECT_EQ(1, r.pieces());
1303
1304 r.clear();
1305 FATAL_EXPECT_TRUE(r.empty());
1306 FATAL_EXPECT_EQ("", r);
1307 FATAL_EXPECT_EQ(0, r.pieces());
1308
1309 r.append(string_view(" "));
1310 FATAL_EXPECT_FALSE(r.empty());
1311 FATAL_EXPECT_EQ(" ", r);
1312 FATAL_EXPECT_EQ(1, r.pieces());
1313
1314 r.clear();
1315 FATAL_EXPECT_TRUE(r.empty());
1316 FATAL_EXPECT_EQ("", r);
1317 FATAL_EXPECT_EQ(0, r.pieces());
1318
1319 std::string three("three");
1320 r.append(three);
1321 FATAL_EXPECT_FALSE(r.empty());
1322 FATAL_EXPECT_EQ("three", r);
1323 FATAL_EXPECT_EQ(1, r.pieces());
1324
1325 r.clear();
1326 FATAL_EXPECT_TRUE(r.empty());
1327 FATAL_EXPECT_EQ("", r);
1328 FATAL_EXPECT_EQ(0, r.pieces());
1329
1330 std::string f(" f");
1331 r.append(std::move(f));
1332 FATAL_EXPECT_FALSE(r.empty());
1333 FATAL_EXPECT_EQ(" f", r);
1334 FATAL_EXPECT_EQ(1, r.pieces());
1335
1336 r.clear();
1337 FATAL_EXPECT_TRUE(r.empty());
1338 FATAL_EXPECT_EQ("", r);
1339 FATAL_EXPECT_EQ(0, r.pieces());
1340
1341 std::string const o("o");
1342 r.append(o);
1343 FATAL_EXPECT_FALSE(r.empty());
1344 FATAL_EXPECT_EQ("o", r);
1345 FATAL_EXPECT_EQ(1, r.pieces());
1346
1347 r.clear();
1348 FATAL_EXPECT_TRUE(r.empty());
1349 FATAL_EXPECT_EQ("", r);
1350 FATAL_EXPECT_EQ(0, r.pieces());
1351
1352 string_view const ur("ur");
1353 r.append(ur);
1354 FATAL_EXPECT_FALSE(r.empty());
1355 FATAL_EXPECT_EQ("ur", r);
1356 FATAL_EXPECT_EQ(1, r.pieces());
1357
1358 r.clear();
1359 FATAL_EXPECT_TRUE(r.empty());
1360 FATAL_EXPECT_EQ("", r);
1361 FATAL_EXPECT_EQ(0, r.pieces());
1362
1363 string_view end("!");
1364 r.append(end);
1365 FATAL_EXPECT_FALSE(r.empty());
1366 FATAL_EXPECT_EQ("!", r);
1367 FATAL_EXPECT_EQ(1, r.pieces());
1368
1369 r.clear();
1370 FATAL_EXPECT_TRUE(r.empty());
1371 FATAL_EXPECT_EQ("", r);
1372 FATAL_EXPECT_EQ(0, r.pieces());
1373 }
1374
FATAL_TEST(clear,two)1375 FATAL_TEST(clear, two) {
1376 rope<> r;
1377 FATAL_EXPECT_TRUE(r.empty());
1378 FATAL_EXPECT_EQ("", r);
1379 FATAL_EXPECT_EQ(0, r.pieces());
1380
1381 r.multi_append("one", ' ');
1382 FATAL_EXPECT_FALSE(r.empty());
1383 FATAL_EXPECT_EQ("one ", r);
1384 FATAL_EXPECT_EQ(2, r.pieces());
1385
1386 r.clear();
1387 FATAL_EXPECT_TRUE(r.empty());
1388 FATAL_EXPECT_EQ("", r);
1389 FATAL_EXPECT_EQ(0, r.pieces());
1390
1391 r.multi_append(std::string("two"), string_view(" "));
1392 FATAL_EXPECT_FALSE(r.empty());
1393 FATAL_EXPECT_EQ("two ", r);
1394 FATAL_EXPECT_EQ(2, r.pieces());
1395
1396 r.clear();
1397 FATAL_EXPECT_TRUE(r.empty());
1398 FATAL_EXPECT_EQ("", r);
1399 FATAL_EXPECT_EQ(0, r.pieces());
1400
1401 std::string three("three");
1402 string_view space(" ");
1403 r.multi_append(three, space);
1404 FATAL_EXPECT_FALSE(r.empty());
1405 FATAL_EXPECT_EQ("three ", r);
1406 FATAL_EXPECT_EQ(2, r.pieces());
1407
1408 r.clear();
1409 FATAL_EXPECT_TRUE(r.empty());
1410 FATAL_EXPECT_EQ("", r);
1411 FATAL_EXPECT_EQ(0, r.pieces());
1412
1413 std::string f(" f");
1414 std::string const o("o");
1415 r.multi_append(std::move(f), o);
1416 FATAL_EXPECT_FALSE(r.empty());
1417 FATAL_EXPECT_EQ(" fo", r);
1418 FATAL_EXPECT_EQ(2, r.pieces());
1419
1420 r.clear();
1421 FATAL_EXPECT_TRUE(r.empty());
1422 FATAL_EXPECT_EQ("", r);
1423 FATAL_EXPECT_EQ(0, r.pieces());
1424
1425 string_view const ur("ur");
1426 string_view end("!");
1427 r.multi_append(ur, end);
1428 FATAL_EXPECT_FALSE(r.empty());
1429 FATAL_EXPECT_EQ("ur!", r);
1430 FATAL_EXPECT_EQ(2, r.pieces());
1431
1432 r.clear();
1433 FATAL_EXPECT_TRUE(r.empty());
1434 FATAL_EXPECT_EQ("", r);
1435 FATAL_EXPECT_EQ(0, r.pieces());
1436 }
1437
FATAL_TEST(clear,three)1438 FATAL_TEST(clear, three) {
1439 rope<> r;
1440 FATAL_EXPECT_TRUE(r.empty());
1441 FATAL_EXPECT_EQ("", r);
1442 FATAL_EXPECT_EQ(0, r.pieces());
1443
1444 r.multi_append("one", ' ', std::string("two"));
1445 FATAL_EXPECT_FALSE(r.empty());
1446 FATAL_EXPECT_EQ("one two", r);
1447 FATAL_EXPECT_EQ(3, r.pieces());
1448
1449 r.clear();
1450 FATAL_EXPECT_TRUE(r.empty());
1451 FATAL_EXPECT_EQ("", r);
1452 FATAL_EXPECT_EQ(0, r.pieces());
1453
1454 std::string three("three");
1455 std::string f(" f");
1456
1457 r.multi_append(string_view(" "), three, std::move(f));
1458 FATAL_EXPECT_FALSE(r.empty());
1459 FATAL_EXPECT_EQ(" three f", r);
1460 FATAL_EXPECT_EQ(3, r.pieces());
1461
1462 r.clear();
1463 FATAL_EXPECT_TRUE(r.empty());
1464 FATAL_EXPECT_EQ("", r);
1465 FATAL_EXPECT_EQ(0, r.pieces());
1466
1467 std::string const o("o");
1468 string_view const ur("ur");
1469 string_view end("!");
1470
1471 r.multi_append(o, ur, end);
1472 FATAL_EXPECT_FALSE(r.empty());
1473 FATAL_EXPECT_EQ("our!", r);
1474 FATAL_EXPECT_EQ(3, r.pieces());
1475
1476 r.clear();
1477 FATAL_EXPECT_TRUE(r.empty());
1478 FATAL_EXPECT_EQ("", r);
1479 FATAL_EXPECT_EQ(0, r.pieces());
1480 }
1481
FATAL_TEST(clear,many)1482 FATAL_TEST(clear, many) {
1483 rope<> r;
1484 FATAL_EXPECT_TRUE(r.empty());
1485 FATAL_EXPECT_EQ("", r);
1486 FATAL_EXPECT_EQ(0, r.pieces());
1487
1488 r.multi_append("one", ' ', std::string("two"), string_view(" "));
1489 FATAL_EXPECT_FALSE(r.empty());
1490 FATAL_EXPECT_EQ("one two ", r);
1491 FATAL_EXPECT_EQ(4, r.pieces());
1492
1493 r.clear();
1494 FATAL_EXPECT_TRUE(r.empty());
1495 FATAL_EXPECT_EQ("", r);
1496 FATAL_EXPECT_EQ(0, r.pieces());
1497
1498 std::string three("three");
1499 std::string const ou("ou");
1500 string_view end("!");
1501
1502 r.multi_append(three, " ", 'f', ou, std::string("r"), end);
1503 FATAL_EXPECT_FALSE(r.empty());
1504 FATAL_EXPECT_EQ("three four!", r);
1505 FATAL_EXPECT_EQ(6, r.pieces());
1506
1507 r.clear();
1508 FATAL_EXPECT_TRUE(r.empty());
1509 FATAL_EXPECT_EQ("", r);
1510 FATAL_EXPECT_EQ(0, r.pieces());
1511 }
1512
1513 //////////
1514 // find //
1515 //////////
1516
1517 template <typename T>
find_char_test(std::chrono::milliseconds time,std::size_t minimum_iterations,T && fn)1518 void find_char_test(
1519 std::chrono::milliseconds time,
1520 std::size_t minimum_iterations,
1521 T &&fn
1522 ) {
1523 std::string const alphabet(
1524 "0123456789"
1525 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1526 "abcdefghijklmnopqrstuvwxyz"
1527 );
1528
1529 random_data rdg;
1530
1531 for (std::size_t size = 30; size; --size) {
1532 std::string s(size, '\0');
1533 rdg.string(s.begin(), s.end(), alphabet.data(), alphabet.size());
1534
1535 auto const begin = s.data();
1536 auto const end = std::next(begin, signed_cast(s.size()));
1537
1538 for (timed_iterations<> i(time, minimum_iterations); i.next(); ) {
1539 rope<> r;
1540 auto const pieces = rdg.chop(
1541 begin, end,
1542 [&](char const *b, char const *e) { r.append(b, e); }
1543 );
1544 FATAL_EXPECT_EQ(pieces, r.pieces());
1545 FATAL_EXPECT_EQ(s, r);
1546
1547 fn(s, r, alphabet);
1548 }
1549 }
1550 }
1551
FATAL_TEST(find,char)1552 FATAL_TEST(find, char) {
1553 find_char_test(
1554 std::chrono::milliseconds(100), 1000,
1555 [](
1556 std::string const &s,
1557 rope<> const &r,
1558 std::string const &alphabet
1559 ) {
1560 for (auto c: alphabet) {
1561 auto expected = s.find(c);
1562 if (expected == std::string::npos) {
1563 expected = s.size();
1564 } else {
1565 assert(expected != s.size());
1566 }
1567
1568 auto const actual = r.find(c);
1569 FATAL_EXPECT_EQ(expected, actual.absolute());
1570 }
1571 }
1572 );
1573 }
1574
FATAL_TEST(find,char size_type)1575 FATAL_TEST(find, char size_type) {
1576 find_char_test(
1577 std::chrono::milliseconds(100), 1000,
1578 [](
1579 std::string const &s,
1580 rope<> const &r,
1581 std::string const &alphabet
1582 ) {
1583 for (auto offset = s.size() + 1; offset--; ) {
1584 for (auto c: alphabet) {
1585 auto expected = s.find(c, offset);
1586 if (expected == std::string::npos) {
1587 expected = s.size();
1588 } else {
1589 assert(expected != s.size());
1590 }
1591
1592 auto const actual = r.find(c, offset);
1593 FATAL_EXPECT_EQ(expected, actual.absolute());
1594 }
1595 }
1596 }
1597 );
1598 }
1599
FATAL_TEST(find,char const_iterator)1600 FATAL_TEST(find, char const_iterator) {
1601 find_char_test(
1602 std::chrono::milliseconds(100), 1000,
1603 [](
1604 std::string const &s,
1605 rope<> const &r,
1606 std::string const &alphabet
1607 ) {
1608 for (auto offset = s.size() + 1; offset--; ) {
1609 auto const r_offset = std::next(r.begin(), signed_cast(offset));
1610 FATAL_EXPECT_EQ(offset, r_offset.absolute());
1611
1612 for (auto c: alphabet) {
1613 auto expected = s.find(c, offset);
1614 if (expected == std::string::npos) {
1615 expected = s.size();
1616 } else {
1617 assert(expected != s.size());
1618 }
1619
1620 auto const actual = r.find(c, r_offset);
1621 FATAL_EXPECT_EQ(expected, actual.absolute());
1622 }
1623 }
1624 }
1625 );
1626 }
1627
1628 /* TODO: IMPLEMENT
1629 FATAL_TEST(find, TODO) {
1630 // TODO: IMPLEMENT
1631 FATAL_EXPECT_UNREACHABLE();
1632 }
1633
1634 ///////////
1635 // rfind //
1636 ///////////
1637
1638 FATAL_TEST(rfind, TODO) {
1639 // TODO: IMPLEMENT
1640 FATAL_EXPECT_UNREACHABLE();
1641 }
1642
1643 ///////////////////
1644 // find_first_of //
1645 ///////////////////
1646
1647 FATAL_TEST(find_first_of, TODO) {
1648 // TODO: IMPLEMENT
1649 FATAL_EXPECT_UNREACHABLE();
1650 }
1651
1652 ///////////////////////
1653 // find_first_not_of //
1654 ///////////////////////
1655
1656 FATAL_TEST(find_first_not_of, TODO) {
1657 // TODO: IMPLEMENT
1658 FATAL_EXPECT_UNREACHABLE();
1659 }
1660
1661 //////////////////
1662 // find_last_of //
1663 //////////////////
1664
1665 FATAL_TEST(find_last_of, TODO) {
1666 // TODO: IMPLEMENT
1667 FATAL_EXPECT_UNREACHABLE();
1668 }
1669
1670 //////////////////////
1671 // find_last_not_of //
1672 //////////////////////
1673
1674 FATAL_TEST(find_last_not_of, TODO) {
1675 // TODO: IMPLEMENT
1676 FATAL_EXPECT_UNREACHABLE();
1677 }
1678 */
1679
1680 ///////////////
1681 // iterators //
1682 ///////////////
1683
FATAL_TEST(const_iterator,empty)1684 FATAL_TEST(const_iterator, empty) {
1685 rope<> r;
1686
1687 FATAL_EXPECT_EQ(r.cbegin(), r.begin());
1688 FATAL_EXPECT_EQ(r.cend(), r.end());
1689 FATAL_EXPECT_EQ(r.cbegin(), r.cend());
1690 FATAL_EXPECT_EQ(r.begin(), r.end());
1691 }
1692
FATAL_TEST(const_iterator,foreach)1693 FATAL_TEST(const_iterator, foreach) {
1694 # define TEST_IMPL(...) \
1695 do { \
1696 rope<> r(__VA_ARGS__); \
1697 auto const s = to_string(__VA_ARGS__); \
1698 auto const begin = s.begin(); \
1699 auto const end = s.end(); \
1700 auto j = begin; \
1701 std::size_t n = 0; \
1702 for (auto const i: r) { \
1703 FATAL_ASSERT_LT(j, end); \
1704 FATAL_EXPECT_EQ(*j, i); \
1705 ++j; \
1706 ++n; \
1707 } \
1708 FATAL_EXPECT_EQ(n, s.size()); \
1709 FATAL_EXPECT_EQ(j, end); \
1710 } while (false)
1711
1712 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1713
1714 # undef TEST_IMPL
1715 }
1716
1717 FATAL_TEST(const_iterator, foreach (prefix ++)) {
1718 # define TEST_IMPL(...) \
1719 do { \
1720 rope<> r(__VA_ARGS__); \
1721 auto const s = to_string(__VA_ARGS__); \
1722 auto const begin = s.begin(); \
1723 auto const end = s.end(); \
1724 auto j = begin; \
1725 auto const b = r.begin(); \
1726 auto const e = r.end(); \
1727 auto i = b; \
1728 std::size_t n = 0; \
1729 for (; i != e; ++i, ++j, ++n) { \
1730 FATAL_ASSERT_LT(j, end); \
1731 FATAL_ASSERT_NE(i, e); \
1732 FATAL_ASSERT_LT(i, e); \
1733 FATAL_ASSERT_GE(i, b); \
1734 FATAL_ASSERT_GT(e, i); \
1735 FATAL_ASSERT_LE(b, i); \
1736 FATAL_EXPECT_EQ(*j, *i); \
1737 } \
1738 FATAL_EXPECT_EQ(n, s.size()); \
1739 FATAL_EXPECT_EQ(j, end); \
1740 FATAL_EXPECT_EQ(i, e); \
1741 } while (false)
1742
1743 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1744
1745 # undef TEST_IMPL
1746 }
1747
1748 FATAL_TEST(const_iterator, foreach (postfix ++)) {
1749 # define TEST_IMPL(...) \
1750 do { \
1751 rope<> r(__VA_ARGS__); \
1752 auto const s = to_string(__VA_ARGS__); \
1753 auto const begin = s.begin(); \
1754 auto const end = s.end(); \
1755 auto j = begin; \
1756 auto const b = r.begin(); \
1757 auto const e = r.end(); \
1758 auto i = b; \
1759 std::size_t n = 0; \
1760 for (; i != e; i++, ++j, ++n) { \
1761 FATAL_ASSERT_LT(j, end); \
1762 FATAL_ASSERT_NE(i, e); \
1763 FATAL_ASSERT_LT(i, e); \
1764 FATAL_ASSERT_GE(i, b); \
1765 FATAL_ASSERT_GT(e, i); \
1766 FATAL_ASSERT_LE(b, i); \
1767 FATAL_EXPECT_EQ(*j, *i); \
1768 } \
1769 FATAL_EXPECT_EQ(n, s.size()); \
1770 FATAL_EXPECT_EQ(j, end); \
1771 FATAL_EXPECT_EQ(i, e); \
1772 } while (false)
1773
1774 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1775
1776 # undef TEST_IMPL
1777 }
1778
1779 FATAL_TEST(const_iterator, foreach (prefix --)) {
1780 # define TEST_IMPL(...) \
1781 do { \
1782 rope<> r(__VA_ARGS__); \
1783 auto const s = to_string(__VA_ARGS__); \
1784 auto const begin = s.begin(); \
1785 auto const end = s.end(); \
1786 auto j = end; \
1787 auto const b = r.begin(); \
1788 auto const e = r.end(); \
1789 auto i = e; \
1790 std::size_t n = 0; \
1791 for (; i != b; ++n) { \
1792 --i; \
1793 --j; \
1794 FATAL_ASSERT_GE(j, begin); \
1795 FATAL_ASSERT_LT(j, end); \
1796 FATAL_ASSERT_NE(i, e); \
1797 FATAL_ASSERT_LT(i, e); \
1798 FATAL_ASSERT_GE(i, b); \
1799 FATAL_ASSERT_GT(e, i); \
1800 FATAL_ASSERT_LE(b, i); \
1801 FATAL_EXPECT_EQ(*j, *i); \
1802 } \
1803 FATAL_EXPECT_EQ(n, s.size()); \
1804 FATAL_EXPECT_EQ(i, b); \
1805 FATAL_EXPECT_EQ(j, begin); \
1806 } while (false)
1807
1808 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1809
1810 # undef TEST_IMPL
1811 }
1812
1813 FATAL_TEST(const_iterator, foreach (postfix --)) {
1814 # define TEST_IMPL(...) \
1815 do { \
1816 rope<> r(__VA_ARGS__); \
1817 auto const s = to_string(__VA_ARGS__); \
1818 auto const begin = s.begin(); \
1819 auto const end = s.end(); \
1820 auto j = end; \
1821 auto const b = r.begin(); \
1822 auto const e = r.end(); \
1823 auto i = e; \
1824 std::size_t n = 0; \
1825 for (; i != b; ++n) { \
1826 i--; \
1827 --j; \
1828 FATAL_ASSERT_GE(j, begin); \
1829 FATAL_ASSERT_LT(j, end); \
1830 FATAL_ASSERT_NE(i, e); \
1831 FATAL_ASSERT_LT(i, e); \
1832 FATAL_ASSERT_GE(i, b); \
1833 FATAL_ASSERT_GT(e, i); \
1834 FATAL_ASSERT_LE(b, i); \
1835 FATAL_EXPECT_EQ(*j, *i); \
1836 } \
1837 FATAL_EXPECT_EQ(n, s.size()); \
1838 FATAL_EXPECT_EQ(i, b); \
1839 FATAL_EXPECT_EQ(j, begin); \
1840 } while (false)
1841
1842 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1843
1844 # undef TEST_IMPL
1845 }
1846
1847 FATAL_TEST(const_iterator, foreach (+= 1)) {
1848 # define TEST_IMPL(...) \
1849 do { \
1850 rope<> r(__VA_ARGS__); \
1851 auto const s = to_string(__VA_ARGS__); \
1852 auto const begin = s.begin(); \
1853 auto const end = s.end(); \
1854 auto j = begin; \
1855 auto const b = r.begin(); \
1856 auto const e = r.end(); \
1857 auto i = b; \
1858 std::size_t n = 0; \
1859 for (; i != e; i += 1, ++j, ++n) { \
1860 FATAL_ASSERT_LT(j, end); \
1861 FATAL_ASSERT_NE(i, e); \
1862 FATAL_ASSERT_LT(i, e); \
1863 FATAL_ASSERT_GE(i, b); \
1864 FATAL_ASSERT_GT(e, i); \
1865 FATAL_ASSERT_LE(b, i); \
1866 FATAL_EXPECT_EQ(*j, *i); \
1867 } \
1868 FATAL_EXPECT_EQ(n, s.size()); \
1869 FATAL_EXPECT_EQ(j, end); \
1870 FATAL_EXPECT_EQ(i, e); \
1871 } while (false)
1872
1873 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1874
1875 # undef TEST_IMPL
1876 }
1877
1878 FATAL_TEST(const_iterator, foreach (-= 1)) {
1879 # define TEST_IMPL(...) \
1880 do { \
1881 rope<> r(__VA_ARGS__); \
1882 auto const s = to_string(__VA_ARGS__); \
1883 auto const begin = s.begin(); \
1884 auto const end = s.end(); \
1885 auto j = end; \
1886 auto const b = r.begin(); \
1887 auto const e = r.end(); \
1888 auto i = e; \
1889 std::size_t n = 0; \
1890 for (; i != b; ++n) { \
1891 i -= 1; \
1892 --j; \
1893 FATAL_ASSERT_GE(j, begin); \
1894 FATAL_ASSERT_LT(j, end); \
1895 FATAL_ASSERT_NE(i, e); \
1896 FATAL_ASSERT_LT(i, e); \
1897 FATAL_ASSERT_GE(i, b); \
1898 FATAL_ASSERT_GT(e, i); \
1899 FATAL_ASSERT_LE(b, i); \
1900 FATAL_EXPECT_EQ(*j, *i); \
1901 } \
1902 FATAL_EXPECT_EQ(n, s.size()); \
1903 FATAL_EXPECT_EQ(i, b); \
1904 FATAL_EXPECT_EQ(j, begin); \
1905 } while (false)
1906
1907 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1908
1909 # undef TEST_IMPL
1910 }
1911
1912 //////////
1913 // hash //
1914 //////////
1915
FATAL_TEST(rope,hasher)1916 FATAL_TEST(rope, hasher) {
1917 # define TEST_IMPL(...) \
1918 do { \
1919 rope<> r1(__VA_ARGS__); \
1920 rope<> r2(to_string(__VA_ARGS__)); \
1921 using hasher = rope<>::hasher; \
1922 FATAL_EXPECT_EQ(hasher()(r1), hasher()(r2)); \
1923 } while (false)
1924
1925 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1926
1927 # undef TEST_IMPL
1928 }
1929
1930 /////////////
1931 // ostream //
1932 /////////////
1933
FATAL_TEST(std,ostream)1934 FATAL_TEST(std, ostream) {
1935 # define TEST_IMPL(...) \
1936 do { \
1937 rope<> r(__VA_ARGS__); \
1938 std::ostringstream ss; \
1939 ss << r; \
1940 auto const expected = to_string(__VA_ARGS__); \
1941 FATAL_EXPECT_EQ(expected, ss.str()); \
1942 } while (false)
1943
1944 TEST_IMPL_SINGLE_STRING(TEST_IMPL);
1945
1946 # undef TEST_IMPL
1947 }
1948
1949 } // namespace fatal {
1950