71 #ifndef LIB_SPLIT_SPLICE_H 72 #define LIB_SPLIT_SPLICE_H 87 namespace splitsplice {
125 using OptORD = std::optional<ORD>;
159 ,CREATE fun_createSeg
164 ,POS startAll, POS afterAll
165 ,OptORD start, OptORD after)
166 : getStart{fun_getStart}
167 , getAfter{fun_getAfter}
168 , createSeg{fun_createSeg}
169 , emptySeg{fun_emptySeg}
170 , cloneSeg{fun_cloneSeg}
171 , discard {fun_discard}
178 ENSURE (pred_ != afterAll);
179 ENSURE (succ_ != afterAll);
180 ENSURE (b_.start < b_.after);
181 ENSURE (getStart(pred_) <= b_.start);
182 ENSURE (b_.start <= getStart(succ_) or pred_ == succ_);
192 ,OptORD start, OptORD after)
194 ORD sep = start? *start
199 for (succ_ = startAll, pred_ = afterAll
200 ;succ_ != afterAll and getStart(succ_) < sep
205 REQUIRE (pred_ != succ_,
"non-empty segmentation required");
206 if (succ_ == afterAll) succ_=pred_;
207 if (pred_ == afterAll) pred_=succ_;
211 ORD startSeg = start? *start
212 : getAfter(pred_) < sep? getAfter(pred_)
214 ORD afterSeg = after? *after
215 : getStart(succ_) > sep? getStart(succ_)
217 ENSURE (startSeg != afterSeg);
218 if (startSeg < afterSeg)
219 return {startSeg,afterSeg};
221 return {afterSeg,startSeg};
233 ORD startPred = getStart (pred_),
234 afterPred = getAfter (pred_);
236 if (startPred < b_.start)
238 if (afterPred < b_.start) opPred_ = INS_NOP;
240 if (afterPred == b_.start) opPred_ = SEAMLESS;
244 if (afterPred > b_.after)
253 REQUIRE (startPred == b_.start,
"predecessor does not precede start point");
255 if (b_.after < afterPred )
263 ORD startSucc = getStart (succ_);
264 if (startSucc < b_.after)
266 while (getAfter(succ_) < b_.after)
268 ASSERT (getStart(succ_) < b_.after
269 ,
"seamless segmentation");
271 if (b_.after == getAfter(succ_)) opSucc_ = DROP;
273 if (b_.after < getAfter(succ_)) opSucc_ = TRUNC;
277 if (b_.after == startSucc) opSucc_ = SEAMLESS;
278 else opSucc_ = INS_NOP;
293 POS refPred = pred_, refSucc = succ_;
294 REQUIRE (opPred_ != NIL and opSucc_ != NIL);
298 if (opPred_ == INS_NOP or opPred_ == SEAMLESS)
300 if (opSucc_ == DROP or opSucc_ == TRUNC)
305 POS n = createSeg (insPos, b_.start, b_.after);
309 if (opPred_ == INS_NOP)
310 s = emptySeg (n, getAfter(refPred), b_.start);
312 if (opPred_ == TRUNC)
313 s = cloneSeg (n, getStart(refPred), b_.start, refPred);
316 if (opSucc_ == INS_NOP)
317 emptySeg (insPos, b_.after, getStart(refSucc));
319 if (opSucc_ == TRUNC)
320 cloneSeg (insPos, b_.after, getAfter(refSucc), refSucc);
323 POS e = discard (insPos, succ_);
#define ASSERT_VALID_SIGNATURE(_FUN_, _SIG_)
Macro for a compile-time check to verify the given generic functors or lambdas expose some expected s...
std::array< POS, 3 > performSplitSplice()
Stage-4 of the algorithm performs the actual insert and deleting of segments.
Any copy and copy construction prohibited.
SegBounds establishSplitPoint(POS startAll, POS afterAll, OptORD start, OptORD after)
Stage-1 and Stage-2 of the algorithm determine the insert point and establish the actual start and en...
void determineRelations()
Stage-3 of the algorithm works out the precise relation of the predecessor and successor segments to ...
Implementation namespace for support and library code.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Metaprogramming tools for transforming functor types.
Algo(START fun_getStart, AFTER fun_getAfter, CREATE fun_createSeg, EMPTY fun_emptySeg, CLONE fun_cloneSeg, DELETE fun_discard, const ORD axisEnd, POS startAll, POS afterAll, OptORD start, OptORD after)
Setup for a single SplitSplice-operation to insert a new segment start to after.
Lumiera error handling (C++ interface).
Implementation of »SplitSplice« algorithm.
a family of time value like entities and their relationships.