Segmentation: setup for simple demo test case works
due to having extracted the Algo implementation as template, we can now instantiate it for isolated tests with simple integer intervals
This commit is contained in:
parent
00ca84a2aa
commit
f9a4d6134c
3 changed files with 139 additions and 63 deletions
|
|
@ -79,22 +79,6 @@ namespace lib {
|
|||
class Algo
|
||||
: util::NonCopyable
|
||||
{
|
||||
enum Verb { NIL
|
||||
, DROP
|
||||
, TRUNC
|
||||
, INS_NOP
|
||||
, SEAMLESS
|
||||
};
|
||||
|
||||
Verb opPred_ = NIL,
|
||||
opSucc_ = NIL;
|
||||
|
||||
POS pred_, succ_;
|
||||
ORD start_, after_;
|
||||
|
||||
using OptORD = std::optional<ORD>;
|
||||
|
||||
|
||||
/* ======= elementary operations ======= */
|
||||
|
||||
ASSERT_VALID_SIGNATURE (START, ORD(POS))
|
||||
|
|
@ -111,8 +95,30 @@ namespace lib {
|
|||
CLONE cloneSeg;
|
||||
DELETE discard;
|
||||
|
||||
using OptORD = std::optional<ORD>;
|
||||
const ORD AXIS_END;
|
||||
|
||||
|
||||
/* ======= working state ======= */
|
||||
|
||||
POS pred_, succ_;
|
||||
|
||||
struct SegBounds
|
||||
{ // can be assigned in one step (ORD may be immutable)
|
||||
ORD start,
|
||||
after;
|
||||
} b_;
|
||||
|
||||
enum Verb { NIL
|
||||
, DROP
|
||||
, TRUNC
|
||||
, INS_NOP
|
||||
, SEAMLESS
|
||||
};
|
||||
|
||||
Verb opPred_ = NIL,
|
||||
opSucc_ = NIL;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @param startAll (forward) iterator pointing at the overall Segmentation begin
|
||||
|
|
@ -136,15 +142,16 @@ namespace lib {
|
|||
, cloneSeg{fun_cloneSeg}
|
||||
, discard {fun_discard}
|
||||
, AXIS_END{axisEnd}
|
||||
, pred_{}
|
||||
, succ_{}
|
||||
, b_{establishSplitPoint (startAll,afterAll, start,after)}
|
||||
{
|
||||
auto [start_,after_] = establishSplitPoint (startAll,afterAll, start,after);
|
||||
|
||||
// Postcondition: ordered start and end times
|
||||
ENSURE (pred_ != afterAll);
|
||||
ENSURE (succ_ != afterAll);
|
||||
ENSURE (start_ < after_);
|
||||
ENSURE (getStart(pred_) <= start_);
|
||||
ENSURE (start_ <= getStart(succ_) or pred_ == succ_);
|
||||
ENSURE (b_.start < b_.after);
|
||||
ENSURE (getStart(pred_) <= b_.start);
|
||||
ENSURE (b_.start <= getStart(succ_) or pred_ == succ_);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -152,7 +159,7 @@ namespace lib {
|
|||
* and establish the actual start and end point of the new segment
|
||||
* @return
|
||||
*/
|
||||
std::pair<ORD,ORD>
|
||||
SegBounds
|
||||
establishSplitPoint (POS startAll, POS afterAll
|
||||
,OptORD start, OptORD after)
|
||||
{ // nominal break point
|
||||
|
|
@ -197,15 +204,15 @@ namespace lib {
|
|||
ORD startPred = getStart (pred_),
|
||||
afterPred = getAfter (pred_);
|
||||
|
||||
if (startPred < start_)
|
||||
if (startPred < b_.start)
|
||||
{
|
||||
if (afterPred < start_) opPred_ = INS_NOP;
|
||||
if (afterPred < b_.start) opPred_ = INS_NOP;
|
||||
else
|
||||
if (afterPred == start_) opPred_ = SEAMLESS;
|
||||
if (afterPred == b_.start) opPred_ = SEAMLESS;
|
||||
else
|
||||
{
|
||||
opPred_ = TRUNC;
|
||||
if (afterPred > after_)
|
||||
if (afterPred > b_.after)
|
||||
{ // predecessor actually spans the new segment
|
||||
// thus use it also as successor and truncate both (=SPLIT)
|
||||
succ_ = pred_;
|
||||
|
|
@ -214,9 +221,9 @@ namespace lib {
|
|||
} } }
|
||||
else
|
||||
{
|
||||
REQUIRE (startPred == start_, "predecessor does not precede start point");
|
||||
REQUIRE (startPred == b_.start, "predecessor does not precede start point");
|
||||
opPred_ = DROP;
|
||||
if (after_ < afterPred )
|
||||
if (b_.after < afterPred )
|
||||
{ // predecessor coincides with start of new segment
|
||||
// thus use it rather as successor and truncate at start
|
||||
succ_ = pred_;
|
||||
|
|
@ -225,21 +232,21 @@ namespace lib {
|
|||
} }
|
||||
|
||||
ORD startSucc = getStart (succ_);
|
||||
if (startSucc < after_)
|
||||
if (startSucc < b_.after)
|
||||
{
|
||||
while (getAfter(succ_) < after_)
|
||||
while (getAfter(succ_) < b_.after)
|
||||
++succ_;
|
||||
ASSERT (getStart(succ_) < after_ // in case we dropped a successor completely spanned,
|
||||
ASSERT (getStart(succ_) < b_.after // in case we dropped a successor completely spanned,
|
||||
,"seamless segmentation"); // even the next one must start within the new segment
|
||||
|
||||
if (after_ == getAfter(succ_)) opSucc_ = DROP;
|
||||
if (b_.after == getAfter(succ_)) opSucc_ = DROP;
|
||||
else
|
||||
if (after_ < getAfter(succ_)) opSucc_ = TRUNC;
|
||||
if (b_.after < getAfter(succ_)) opSucc_ = TRUNC;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (after_ == startSucc) opSucc_ = SEAMLESS;
|
||||
else opSucc_ = INS_NOP;
|
||||
if (b_.after == startSucc) opSucc_ = SEAMLESS;
|
||||
else opSucc_ = INS_NOP;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,22 +272,22 @@ namespace lib {
|
|||
++succ_;
|
||||
|
||||
// insert the new elements /before/ the range to be dropped, i.e. at pred_
|
||||
POS n = createSeg (pred_, start_, after_);
|
||||
POS n = createSeg (pred_, b_.start, b_.after);
|
||||
POS s = n;
|
||||
//
|
||||
// possibly adapt the predecessor
|
||||
if (opPred_ == INS_NOP)
|
||||
s = emptySeg (n, getAfter(refPred), start_);
|
||||
s = emptySeg (n, getAfter(refPred), b_.start);
|
||||
else
|
||||
if (opPred_ == TRUNC)
|
||||
s = cloneSeg (n, getStart(refPred), start_, refPred);
|
||||
s = cloneSeg (n, getStart(refPred), b_.start, refPred);
|
||||
//
|
||||
// possibly adapt the successor
|
||||
if (opSucc_ == INS_NOP)
|
||||
emptySeg (pred_, after_, getStart(refSucc));
|
||||
emptySeg (pred_, b_.after, getStart(refSucc));
|
||||
else
|
||||
if (opPred_ == TRUNC)
|
||||
cloneSeg (pred_, after_, getAfter(refSucc), refSucc);
|
||||
cloneSeg (pred_, b_.after, getAfter(refSucc), refSucc);
|
||||
|
||||
// finally discard superseded segments
|
||||
POS e = discard (pred_, succ_);
|
||||
|
|
|
|||
|
|
@ -63,6 +63,12 @@ namespace test {
|
|||
int after;
|
||||
bool empty;
|
||||
|
||||
~Seg()
|
||||
{
|
||||
check -= id;
|
||||
if (id) --cnt;
|
||||
}
|
||||
|
||||
Seg (int s, int a, bool nil=false)
|
||||
: start{s}
|
||||
, after{a}
|
||||
|
|
@ -73,12 +79,18 @@ namespace test {
|
|||
check += id;
|
||||
}
|
||||
|
||||
~Seg()
|
||||
/** create a clone, but modify bounds */
|
||||
Seg (Seg const& ref, int s, int a)
|
||||
: start{s}
|
||||
, after{a}
|
||||
, empty{ref.empty}
|
||||
, id{ref.id}
|
||||
{
|
||||
check -= id;
|
||||
if (id) --cnt;
|
||||
++cnt;
|
||||
check += id;
|
||||
}
|
||||
|
||||
/** move-init: causes source-ref to be invalidated */
|
||||
Seg (Seg&& rr)
|
||||
: start{rr.start}
|
||||
, after{rr.after}
|
||||
|
|
@ -222,7 +234,37 @@ namespace test {
|
|||
void
|
||||
demonstrate_usage()
|
||||
{
|
||||
TODO ("simple usage example");
|
||||
SegL segments;
|
||||
cout << segments <<endl;
|
||||
|
||||
using OInt = std::optional<int>;
|
||||
using Iter = typename SegL::iterator;
|
||||
|
||||
auto getStart = [](Iter elm) -> int { return elm->start; };
|
||||
auto getAfter = [](Iter elm) -> int { return elm->after; };
|
||||
auto createSeg= [&](Iter pos, int start, int after) -> Iter { return segments.emplace (pos, start, after); };
|
||||
auto emptySeg = [&](Iter pos, int start, int after) -> Iter { return segments.emplace (pos, start, after, true); };
|
||||
auto cloneSeg = [&](Iter pos, int start, int after, Iter src) -> Iter { return segments.emplace (pos, *src, start, after); };
|
||||
auto discard = [&](Iter pos, Iter after) -> Iter { return segments.erase (pos,after); };
|
||||
|
||||
|
||||
lib::splitsplice::Algo splicer{ getStart
|
||||
, getAfter
|
||||
, createSeg
|
||||
, emptySeg
|
||||
, cloneSeg
|
||||
, discard
|
||||
, SMAX
|
||||
, segments.begin(),segments.end()
|
||||
, OInt{5}, OInt{23}
|
||||
};
|
||||
splicer.determineRelations();
|
||||
auto [s,n,e] = splicer.performSplitSplice();
|
||||
|
||||
cout << segments <<endl;
|
||||
cout << "s:"<<*s <<endl;
|
||||
cout << "n:"<<*n <<endl;
|
||||
cout << "e:"<<*e <<endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -230,6 +272,8 @@ namespace test {
|
|||
void
|
||||
verify_testFixture()
|
||||
{
|
||||
CHECK (0 == Seg::check);
|
||||
Seg::idGen = 0;
|
||||
{
|
||||
Seg x{1,3}; // a segment 1 (inclusive) to 3 (exclusive)
|
||||
Seg u{2,4,true}; // an "empty" segment 2 (incl) to 4 (excl)
|
||||
|
|
|
|||
|
|
@ -70281,25 +70281,7 @@
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1683046958233" ID="ID_226373762" MODIFIED="1683047000567" TEXT="isoliert testbar machen">
|
||||
<arrowlink COLOR="#e31dc4" DESTINATION="ID_1714211009" ENDARROW="Default" ENDINCLINATION="-141;9;" ID="Arrow_ID_816334190" STARTARROW="None" STARTINCLINATION="-192;20;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1682993091685" ID="ID_988617455" MODIFIED="1682993099148" TEXT="systematische Testabdeckung">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node CREATED="1682993100755" ID="ID_1651031348" MODIFIED="1682993128370" TEXT="es sind 12 Basis-Fälle">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1682993108314" ID="ID_317827435" MODIFIED="1682993122827" TEXT="hinzu kommt die Variante, daß leere Intervalle zusammengeführt werden"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1683046966788" ID="ID_1714211009" MODIFIED="1683120265331" TEXT="splitSplice-Algo isoliert testen">
|
||||
<linktarget COLOR="#e31dc4" DESTINATION="ID_1714211009" ENDARROW="Default" ENDINCLINATION="-141;9;" ID="Arrow_ID_816334190" SOURCE="ID_226373762" STARTARROW="None" STARTINCLINATION="-192;20;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1683120139366" ID="ID_255513798" MODIFIED="1683120148509" TEXT="Test-Setup mit einfachen int-Intevallen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1683120149579" ID="ID_523859522" MODIFIED="1683120164828" TEXT="Diagnose-setup für valide Segmentation">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1683120165480" ID="ID_1260440964" MODIFIED="1683120205165" TEXT="Diagnose-Setup für Memory-Management">
|
||||
<node COLOR="#338800" CREATED="1683158281268" ID="ID_1471352554" MODIFIED="1683158303513" TEXT="Verdrahtung für Dummy-Integer-Segmente">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1683153490521" ID="ID_855593043" MODIFIED="1683153582188" TEXT="Diagnose-Helper zum Vergleichen mit erwartetem Inhalt">
|
||||
|
|
@ -70324,6 +70306,49 @@
|
|||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1682993091685" ID="ID_988617455" MODIFIED="1682993099148" TEXT="systematische Testabdeckung">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node CREATED="1682993100755" ID="ID_1651031348" MODIFIED="1682993128370" TEXT="es sind 12 Basis-Fälle">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1682993108314" ID="ID_317827435" MODIFIED="1682993122827" TEXT="hinzu kommt die Variante, daß leere Intervalle zusammengeführt werden"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1683046966788" ID="ID_1714211009" MODIFIED="1683120265331" TEXT="splitSplice-Algo isoliert testen">
|
||||
<linktarget COLOR="#e31dc4" DESTINATION="ID_1714211009" ENDARROW="Default" ENDINCLINATION="-141;9;" ID="Arrow_ID_816334190" SOURCE="ID_226373762" STARTARROW="None" STARTINCLINATION="-192;20;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1683120139366" ID="ID_255513798" MODIFIED="1683120148509" TEXT="Test-Setup mit einfachen int-Intevallen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1683120149579" ID="ID_523859522" MODIFIED="1683120164828" TEXT="Diagnose-setup für valide Segmentation">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1683120165480" ID="ID_1260440964" MODIFIED="1683120205165" TEXT="Diagnose-Setup für Memory-Management">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1683158346179" ID="ID_1729448638" MODIFIED="1683158373910" TEXT="Demonstration: einfache Anwendung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1683158410507" ID="ID_1394829232" MODIFIED="1683158528764">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<font face="Monospaced" color="#2d258b">[-100~100[┤ </font>
|
||||
</p>
|
||||
<p>
|
||||
<font face="Monospaced" color="#2d258b">[-100~5[[5_23[[23~100[┤</font>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1683158382175" ID="ID_1213737514" MODIFIED="1683158390534" TEXT="Setup für Einzelfall-Tests">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1683047015402" ID="ID_1729864005" MODIFIED="1683120259296" TEXT="Mögliche Intervall-Anordnungen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1683047146727" ID="ID_1666065871" MODIFIED="1683047163542" TEXT="Seg in leer">
|
||||
|
|
|
|||
Loading…
Reference in a new issue