37 #include "lib/split-splice.hpp" 77 Seg (
int s,
int a,
bool nil=
false)
105 std::swap (
id, rr.id);
108 operator string()
const 110 return _Fmt{
"[%i%s%i["}
126 size_t Seg::check{0};
130 const int SMIN = -100;
131 const int SMAX = +100;
145 SegL (std::initializer_list<int> breaks)
151 emplace_back (p,b, bound);
155 emplace_back(p,SMAX,
true);
164 operator string()
const 166 return renderContent() + assess();
172 return isnil (this->assess());
176 renderContent()
const 178 return "├"+util::join(*
this,
"")+
"┤";
186 diagnosis =
"!empty!";
189 if (front().start != SMIN)
190 diagnosis +=
"missing-lower-bound!";
191 if (back().after != SMAX)
192 diagnosis +=
"missing-upper-bound!";
194 for (
auto const& s : *
this)
197 diagnosis +=
_Fmt{
"!gap_%i<>%i_!"} % p % s.start;
198 if (s.start == s.after)
199 diagnosis +=
_Fmt{
"!degen_%i_!"} % s.start;
200 if (s.start > s.after)
201 diagnosis +=
_Fmt{
"!order_%i>%i_!"} % s.start % s.after;
214 using OptInt = std::optional<int>;
215 using Iter =
typename SegL::iterator;
234 auto getStart = [](Iter elm) ->
int {
return elm->start; };
235 auto getAfter = [](Iter elm) ->
int {
return elm->after; };
236 auto createSeg= [&](Iter pos,
int start,
int after) -> Iter {
return segs.emplace (pos, start, after); };
237 auto emptySeg = [&](Iter pos,
int start,
int after) -> Iter {
return segs.emplace (pos, start, after,
true); };
238 auto cloneSeg = [&](Iter pos,
int start,
int after, Iter src) -> Iter {
return segs.emplace (pos, *src, start, after); };
239 auto discard = [&](Iter pos, Iter after) -> Iter {
return segs.erase (pos,after); };
249 , segs.begin(),segs.end()
252 splicer.determineRelations();
253 return splicer.performSplitSplice();
276 verify_testFixture();
277 verify_standardCases();
278 verify_cornerCases();
282 CHECK (0 == Seg::check);
283 CHECK (0 == Seg::cnt);
294 CHECK (segmentation ==
"├[-100~100[┤"_expect);
304 CHECK (segmentation ==
"├[-100~5[[5_23[[23~100[┤"_expect);
307 CHECK (segmentation.isValid());
316 CHECK (0 == Seg::check);
321 CHECK (x ==
"[1_3["_expect);
322 CHECK (u ==
"[2~4["_expect);
323 CHECK (3 == Seg::check);
324 CHECK (2 == Seg::cnt);
327 CHECK (z ==
"[2~4["_expect);
328 CHECK (3 == Seg::check);
329 CHECK (2 == Seg::cnt);
336 CHECK (l1 ==
"├[-100~100[┤"_expect);
337 CHECK (l2 ==
"├[-100~3[[3~100[┤"_expect);
338 CHECK (l3 ==
"├[-100~5[[5_-5[[-5_10[[10~100[┤!order_5>-5_!"_expect);
340 CHECK (l1.isValid());
341 CHECK (l2.isValid());
342 CHECK (not l3.isValid());
343 CHECK (l3.assess() ==
"!order_5>-5_!"_expect);
345 CHECK ( 9 == Seg::cnt );
346 CHECK ( 9 == Seg::idGen);
347 CHECK (45 == Seg::check);
349 l3.erase(l3.begin());
350 CHECK (l3.assess() ==
"missing-lower-bound!!gap_-100<>5_!!order_5>-5_!"_expect);
351 CHECK ( 8 == Seg::cnt );
353 l3.begin()->after = 5;
354 CHECK (l3.renderContent() ==
"├[5_5[[-5_10[[10~100[┤"_expect);
355 CHECK (l3.assess() ==
"missing-lower-bound!!gap_-100<>5_!!degen_5_!!gap_5<>-5_!"_expect);
357 CHECK (l3.assess() ==
"!empty!"_expect);
359 CHECK ( 5 == Seg::cnt );
360 CHECK ( 9 == Seg::idGen);
361 CHECK (15 == Seg::check);
364 CHECK (0 == Seg::cnt );
365 CHECK (0 == Seg::check);
366 CHECK (9 == Seg::idGen);
377 auto testCase = [](SegL segmentation
382 OptInt startSpec{startNew},
386 CHECK (segmentation == expectedResult);
387 CHECK (segmentation.isValid());
390 testCase (SegL{}, -23,24,
"├[-100~-23[[-23_24[[24~100[┤"_expect);
393 testCase (SegL{5,10}, 2,3,
"├[-100~2[[2_3[[3~5[[5_10[[10~100[┤"_expect);
394 testCase (SegL{5,10}, 4,5,
"├[-100~4[[4_5[[5_10[[10~100[┤"_expect);
395 testCase (SegL{5,10}, 4,8,
"├[-100~4[[4_8[[8_10[[10~100[┤"_expect);
396 testCase (SegL{5,10}, 5,8,
"├[-100~5[[5_8[[8_10[[10~100[┤"_expect);
397 testCase (SegL{5,10}, 6,8,
"├[-100~5[[5_6[[6_8[[8_10[[10~100[┤"_expect);
398 testCase (SegL{5,10}, 7,10,
"├[-100~5[[5_7[[7_10[[10~100[┤"_expect);
399 testCase (SegL{5,10}, 9,13,
"├[-100~5[[5_9[[9_13[[13~100[┤"_expect);
400 testCase (SegL{5,10}, 10,13,
"├[-100~5[[5_10[[10_13[[13~100[┤"_expect);
401 testCase (SegL{5,10}, 13,23,
"├[-100~5[[5_10[[10~13[[13_23[[23~100[┤"_expect);
404 testCase (SegL{5,10}, 5,10,
"├[-100~5[[5_10[[10~100[┤"_expect);
407 testCase (SegL{5,10}, 3,10,
"├[-100~3[[3_10[[10~100[┤"_expect);
408 testCase (SegL{5,10}, 3,23,
"├[-100~3[[3_23[[23~100[┤"_expect);
409 testCase (SegL{5,10}, 5,23,
"├[-100~5[[5_23[[23~100[┤"_expect);
420 auto testCase = [](SegL segmentation
426 CHECK (segmentation == expectedResult);
427 CHECK (segmentation.isValid());
429 auto x = std::nullopt;
431 testCase (SegL{}, 3,2,
"├[-100~2[[2_3[[3~100[┤"_expect);
433 testCase (SegL{}, 3,x,
"├[-100~3[[3_100[┤"_expect);
434 testCase (SegL{}, x,5,
"├[-100_5[[5~100[┤"_expect);
436 testCase (SegL{4,6}, 5,x,
"├[-100~4[[4_5[[5_6[[6~100[┤"_expect);
437 testCase (SegL{4,6}, x,5,
"├[-100~4[[4_5[[5_6[[6~100[┤"_expect);
439 testCase (SegL{4,6}, 3,x,
"├[-100~3[[3_4[[4_6[[6~100[┤"_expect);
440 testCase (SegL{4,6}, x,3,
"├[-100_3[[3~4[[4_6[[6~100[┤"_expect);
441 testCase (SegL{4,6}, 4,x,
"├[-100~4[[4_6[[6~100[┤"_expect);
442 testCase (SegL{4,6}, x,4,
"├[-100_4[[4_6[[6~100[┤"_expect);
444 testCase (SegL{4,6}, 7,x,
"├[-100~4[[4_6[[6~7[[7_100[┤"_expect);
445 testCase (SegL{4,6}, x,7,
"├[-100~4[[4_6[[6_7[[7~100[┤"_expect);
446 testCase (SegL{4,6}, 6,x,
"├[-100~4[[4_6[[6_100[┤"_expect);
447 testCase (SegL{4,6}, x,6,
"├[-100~4[[4_6[[6~100[┤"_expect);
449 testCase (SegL{}, x,x,
"├[-100_100[┤"_expect);
450 testCase (SegL{4}, x,x,
"├[-100~4[[4_100[┤"_expect);
451 testCase (SegL{4,6}, x,x,
"├[-100~4[[4_6[[6_100[┤"_expect);
453 testCase (SegL{4,5,6,8}, 3,6,
"├[-100~3[[3_6[[6_8[[8~100[┤"_expect);
454 testCase (SegL{4,5,6,8}, 4,6,
"├[-100~4[[4_6[[6_8[[8~100[┤"_expect);
455 testCase (SegL{4,5,6,8}, 4,7,
"├[-100~4[[4_7[[7_8[[8~100[┤"_expect);
456 testCase (SegL{4,5,6,8}, 3,7,
"├[-100~3[[3_7[[7_8[[8~100[┤"_expect);
457 testCase (SegL{4,5,6,8}, 3,8,
"├[-100~3[[3_8[[8~100[┤"_expect);
458 testCase (SegL{4,5,6,8}, 4,8,
"├[-100~4[[4_8[[8~100[┤"_expect);
459 testCase (SegL{4,5,6,8}, 4,9,
"├[-100~4[[4_9[[9~100[┤"_expect);
460 testCase (SegL{4,5,6,8}, 5,9,
"├[-100~4[[4_5[[5_9[[9~100[┤"_expect);
461 testCase (SegL{4,5,6,8}, 5,x,
"├[-100~4[[4_5[[5_6[[6_8[[8~100[┤"_expect);
462 testCase (SegL{4,5,7,8}, x,6,
"├[-100~4[[4_5[[5_6[[6_7[[7_8[[8~100[┤"_expect);
477 CHECK (segs ==
"├[-100~2[[2_6[[6~100[┤"_expect);
479 Iter s = segs.begin();
480 CHECK (s->start == -100);
481 CHECK (s->after == 2);
485 CHECK (s->start == 2);
486 CHECK (s->after == 6);
490 CHECK (s->start == 6);
491 CHECK (s->after == 100);
496 CHECK (5 == segs.size());
497 CHECK (segs ==
"├[-100~2[[2_3[[3_4[[4_6[[6~100[┤"_expect);
500 CHECK (s->start == -100);
501 CHECK (s->after == 2);
502 CHECK (s->id == id1);
503 CHECK (adr1 == getAdr(*s));
507 CHECK (s->start == 2);
508 CHECK (s->after == 3);
509 CHECK (s->id == id2);
510 CHECK (adr2 != getAdr(*s));
514 CHECK (s->start == 3);
515 CHECK (s->after == 4);
516 CHECK (s->id != id1);
517 CHECK (s->id != id2);
518 CHECK (s->id != id3);
519 CHECK (adr2 != getAdr(*s));
523 CHECK (s->start == 4);
524 CHECK (s->after == 6);
525 CHECK (s->id != id1);
526 CHECK (s->id == id2);
527 CHECK (s->id != id3);
528 CHECK (adr2 != getAdr(*s));
531 CHECK (s->start == 6);
532 CHECK (s->after == 100);
533 CHECK (s->id != id1);
534 CHECK (s->id != id2);
535 CHECK (s->id == id3);
536 CHECK (adr3 == getAdr(*s));
538 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...
Simplistic 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, based directly on the referee's memory identities. ...