46 #include "lib/split-splice.hpp" 86 Seg (
int s,
int a,
bool nil=
false)
114 std::swap (
id, rr.id);
117 operator string()
const 119 return _Fmt{
"[%i%s%i["}
135 size_t Seg::check{0};
139 const int SMIN = -100;
140 const int SMAX = +100;
154 SegL (std::initializer_list<int> breaks)
160 emplace_back (p,b, bound);
164 emplace_back(p,SMAX,
true);
173 operator string()
const 175 return renderContent() + assess();
181 return isnil (this->assess());
185 renderContent()
const 187 return "├"+util::join(*
this,
"")+
"┤";
195 diagnosis =
"!empty!";
198 if (front().start != SMIN)
199 diagnosis +=
"missing-lower-bound!";
200 if (back().after != SMAX)
201 diagnosis +=
"missing-upper-bound!";
203 for (
auto const& s : *
this)
206 diagnosis +=
_Fmt{
"!gap_%i<>%i_!"} % p % s.start;
207 if (s.start == s.after)
208 diagnosis +=
_Fmt{
"!degen_%i_!"} % s.start;
209 if (s.start > s.after)
210 diagnosis +=
_Fmt{
"!order_%i>%i_!"} % s.start % s.after;
223 using OptInt = std::optional<int>;
224 using Iter =
typename SegL::iterator;
243 auto getStart = [](Iter elm) ->
int {
return elm->start; };
244 auto getAfter = [](Iter elm) ->
int {
return elm->after; };
245 auto createSeg= [&](Iter pos,
int start,
int after) -> Iter {
return segs.emplace (pos, start, after); };
246 auto emptySeg = [&](Iter pos,
int start,
int after) -> Iter {
return segs.emplace (pos, start, after,
true); };
247 auto cloneSeg = [&](Iter pos,
int start,
int after, Iter src) -> Iter {
return segs.emplace (pos, *src, start, after); };
248 auto discard = [&](Iter pos, Iter after) -> Iter {
return segs.erase (pos,after); };
258 , segs.begin(),segs.end()
261 splicer.determineRelations();
262 return splicer.performSplitSplice();
285 verify_testFixture();
286 verify_standardCases();
287 verify_cornerCases();
291 CHECK (0 == Seg::check);
292 CHECK (0 == Seg::cnt);
303 CHECK (segmentation ==
"├[-100~100[┤"_expect);
313 CHECK (segmentation ==
"├[-100~5[[5_23[[23~100[┤"_expect);
316 CHECK (segmentation.isValid());
325 CHECK (0 == Seg::check);
330 CHECK (x ==
"[1_3["_expect);
331 CHECK (u ==
"[2~4["_expect);
332 CHECK (3 == Seg::check);
333 CHECK (2 == Seg::cnt);
336 CHECK (z ==
"[2~4["_expect);
337 CHECK (3 == Seg::check);
338 CHECK (2 == Seg::cnt);
345 CHECK (l1 ==
"├[-100~100[┤"_expect);
346 CHECK (l2 ==
"├[-100~3[[3~100[┤"_expect);
347 CHECK (l3 ==
"├[-100~5[[5_-5[[-5_10[[10~100[┤!order_5>-5_!"_expect);
349 CHECK (l1.isValid());
350 CHECK (l2.isValid());
351 CHECK (not l3.isValid());
352 CHECK (l3.assess() ==
"!order_5>-5_!"_expect);
354 CHECK ( 9 == Seg::cnt );
355 CHECK ( 9 == Seg::idGen);
356 CHECK (45 == Seg::check);
358 l3.erase(l3.begin());
359 CHECK (l3.assess() ==
"missing-lower-bound!!gap_-100<>5_!!order_5>-5_!"_expect);
360 CHECK ( 8 == Seg::cnt );
362 l3.begin()->after = 5;
363 CHECK (l3.renderContent() ==
"├[5_5[[-5_10[[10~100[┤"_expect);
364 CHECK (l3.assess() ==
"missing-lower-bound!!gap_-100<>5_!!degen_5_!!gap_5<>-5_!"_expect);
366 CHECK (l3.assess() ==
"!empty!"_expect);
368 CHECK ( 5 == Seg::cnt );
369 CHECK ( 9 == Seg::idGen);
370 CHECK (15 == Seg::check);
373 CHECK (0 == Seg::cnt );
374 CHECK (0 == Seg::check);
375 CHECK (9 == Seg::idGen);
386 auto testCase = [](SegL segmentation
391 OptInt startSpec{startNew},
395 CHECK (segmentation == expectedResult);
396 CHECK (segmentation.isValid());
399 testCase (SegL{}, -23,24,
"├[-100~-23[[-23_24[[24~100[┤"_expect);
402 testCase (SegL{5,10}, 2,3,
"├[-100~2[[2_3[[3~5[[5_10[[10~100[┤"_expect);
403 testCase (SegL{5,10}, 4,5,
"├[-100~4[[4_5[[5_10[[10~100[┤"_expect);
404 testCase (SegL{5,10}, 4,8,
"├[-100~4[[4_8[[8_10[[10~100[┤"_expect);
405 testCase (SegL{5,10}, 5,8,
"├[-100~5[[5_8[[8_10[[10~100[┤"_expect);
406 testCase (SegL{5,10}, 6,8,
"├[-100~5[[5_6[[6_8[[8_10[[10~100[┤"_expect);
407 testCase (SegL{5,10}, 7,10,
"├[-100~5[[5_7[[7_10[[10~100[┤"_expect);
408 testCase (SegL{5,10}, 9,13,
"├[-100~5[[5_9[[9_13[[13~100[┤"_expect);
409 testCase (SegL{5,10}, 10,13,
"├[-100~5[[5_10[[10_13[[13~100[┤"_expect);
410 testCase (SegL{5,10}, 13,23,
"├[-100~5[[5_10[[10~13[[13_23[[23~100[┤"_expect);
413 testCase (SegL{5,10}, 5,10,
"├[-100~5[[5_10[[10~100[┤"_expect);
416 testCase (SegL{5,10}, 3,10,
"├[-100~3[[3_10[[10~100[┤"_expect);
417 testCase (SegL{5,10}, 3,23,
"├[-100~3[[3_23[[23~100[┤"_expect);
418 testCase (SegL{5,10}, 5,23,
"├[-100~5[[5_23[[23~100[┤"_expect);
429 auto testCase = [](SegL segmentation
435 CHECK (segmentation == expectedResult);
436 CHECK (segmentation.isValid());
438 auto x = std::nullopt;
440 testCase (SegL{}, 3,2,
"├[-100~2[[2_3[[3~100[┤"_expect);
442 testCase (SegL{}, 3,x,
"├[-100~3[[3_100[┤"_expect);
443 testCase (SegL{}, x,5,
"├[-100_5[[5~100[┤"_expect);
445 testCase (SegL{4,6}, 5,x,
"├[-100~4[[4_5[[5_6[[6~100[┤"_expect);
446 testCase (SegL{4,6}, x,5,
"├[-100~4[[4_5[[5_6[[6~100[┤"_expect);
448 testCase (SegL{4,6}, 3,x,
"├[-100~3[[3_4[[4_6[[6~100[┤"_expect);
449 testCase (SegL{4,6}, x,3,
"├[-100_3[[3~4[[4_6[[6~100[┤"_expect);
450 testCase (SegL{4,6}, 4,x,
"├[-100~4[[4_6[[6~100[┤"_expect);
451 testCase (SegL{4,6}, x,4,
"├[-100_4[[4_6[[6~100[┤"_expect);
453 testCase (SegL{4,6}, 7,x,
"├[-100~4[[4_6[[6~7[[7_100[┤"_expect);
454 testCase (SegL{4,6}, x,7,
"├[-100~4[[4_6[[6_7[[7~100[┤"_expect);
455 testCase (SegL{4,6}, 6,x,
"├[-100~4[[4_6[[6_100[┤"_expect);
456 testCase (SegL{4,6}, x,6,
"├[-100~4[[4_6[[6~100[┤"_expect);
458 testCase (SegL{}, x,x,
"├[-100_100[┤"_expect);
459 testCase (SegL{4}, x,x,
"├[-100~4[[4_100[┤"_expect);
460 testCase (SegL{4,6}, x,x,
"├[-100~4[[4_6[[6_100[┤"_expect);
462 testCase (SegL{4,5,6,8}, 3,6,
"├[-100~3[[3_6[[6_8[[8~100[┤"_expect);
463 testCase (SegL{4,5,6,8}, 4,6,
"├[-100~4[[4_6[[6_8[[8~100[┤"_expect);
464 testCase (SegL{4,5,6,8}, 4,7,
"├[-100~4[[4_7[[7_8[[8~100[┤"_expect);
465 testCase (SegL{4,5,6,8}, 3,7,
"├[-100~3[[3_7[[7_8[[8~100[┤"_expect);
466 testCase (SegL{4,5,6,8}, 3,8,
"├[-100~3[[3_8[[8~100[┤"_expect);
467 testCase (SegL{4,5,6,8}, 4,8,
"├[-100~4[[4_8[[8~100[┤"_expect);
468 testCase (SegL{4,5,6,8}, 4,9,
"├[-100~4[[4_9[[9~100[┤"_expect);
469 testCase (SegL{4,5,6,8}, 5,9,
"├[-100~4[[4_5[[5_9[[9~100[┤"_expect);
470 testCase (SegL{4,5,6,8}, 5,x,
"├[-100~4[[4_5[[5_6[[6_8[[8~100[┤"_expect);
471 testCase (SegL{4,5,7,8}, x,6,
"├[-100~4[[4_5[[5_6[[6_7[[7_8[[8~100[┤"_expect);
486 CHECK (segs ==
"├[-100~2[[2_6[[6~100[┤"_expect);
488 Iter s = segs.begin();
489 CHECK (s->start == -100);
490 CHECK (s->after == 2);
494 CHECK (s->start == 2);
495 CHECK (s->after == 6);
499 CHECK (s->start == 6);
500 CHECK (s->after == 100);
505 CHECK (5 == segs.size());
506 CHECK (segs ==
"├[-100~2[[2_3[[3_4[[4_6[[6~100[┤"_expect);
509 CHECK (s->start == -100);
510 CHECK (s->after == 2);
511 CHECK (s->id == id1);
512 CHECK (adr1 == getAddr(*s));
516 CHECK (s->start == 2);
517 CHECK (s->after == 3);
518 CHECK (s->id == id2);
519 CHECK (adr2 != getAddr(*s));
523 CHECK (s->start == 3);
524 CHECK (s->after == 4);
525 CHECK (s->id != id1);
526 CHECK (s->id != id2);
527 CHECK (s->id != id3);
528 CHECK (adr2 != getAddr(*s));
532 CHECK (s->start == 4);
533 CHECK (s->after == 6);
534 CHECK (s->id != id1);
535 CHECK (s->id == id2);
536 CHECK (s->id != id3);
537 CHECK (adr2 != getAddr(*s));
540 CHECK (s->start == 6);
541 CHECK (s->after == 100);
542 CHECK (s->id != id1);
543 CHECK (s->id != id2);
544 CHECK (s->id == id3);
545 CHECK (adr3 == getAddr(*s));
547 CHECK (s == segs.end());
Helper to produce better diagnostic messages when comparing to an expected result string...
Test-Segmentation comprised of a sequence of Seg entries.
void verify_standardCases()
Types marked with this mix-in may be moved but not copied.
Seg(Seg const &ref, int s, int a)
create a clone, but modify bounds
A front-end for using printf-style formatting.
Implementation namespace for support and library code.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
auto invokeSplitSplice(SegL &segs, OptInt startNew, OptInt afterNew)
Perform the »SplitSplice« Algorithm to splice a new Segment into the given segmentation of the intege...
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
void verify_testFixture()
Seg(Seg &&rr)
move-init: causes source-ref to be invalidated
Implementation of »SplitSplice« algorithm.
Test Dummy: a "segment" representing an integer interval.
void verify_cornerCases()
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.