80 #ifndef LIB_SPLIT_SPLICE_H 81 #define LIB_SPLIT_SPLICE_H 96 namespace splitsplice {
134 using OptORD = std::optional<ORD>;
168 ,CREATE fun_createSeg
173 ,POS startAll, POS afterAll
174 ,OptORD start, OptORD after)
175 : getStart{fun_getStart}
176 , getAfter{fun_getAfter}
177 , createSeg{fun_createSeg}
178 , emptySeg{fun_emptySeg}
179 , cloneSeg{fun_cloneSeg}
180 , discard {fun_discard}
187 ENSURE (pred_ != afterAll);
188 ENSURE (succ_ != afterAll);
189 ENSURE (b_.start < b_.after);
190 ENSURE (getStart(pred_) <= b_.start);
191 ENSURE (b_.start <= getStart(succ_) or pred_ == succ_);
201 ,OptORD start, OptORD after)
203 ORD sep = start? *start
208 for (succ_ = startAll, pred_ = afterAll
209 ;succ_ != afterAll and getStart(succ_) < sep
214 REQUIRE (pred_ != succ_,
"non-empty segmentation required");
215 if (succ_ == afterAll) succ_=pred_;
216 if (pred_ == afterAll) pred_=succ_;
220 ORD startSeg = start? *start
221 : getAfter(pred_) < sep? getAfter(pred_)
223 ORD afterSeg = after? *after
224 : getStart(succ_) > sep? getStart(succ_)
226 ENSURE (startSeg != afterSeg);
227 if (startSeg < afterSeg)
228 return {startSeg,afterSeg};
230 return {afterSeg,startSeg};
242 ORD startPred = getStart (pred_),
243 afterPred = getAfter (pred_);
245 if (startPred < b_.start)
247 if (afterPred < b_.start) opPred_ = INS_NOP;
249 if (afterPred == b_.start) opPred_ = SEAMLESS;
253 if (afterPred > b_.after)
262 REQUIRE (startPred == b_.start,
"predecessor does not precede start point");
264 if (b_.after < afterPred )
272 ORD startSucc = getStart (succ_);
273 if (startSucc < b_.after)
275 while (getAfter(succ_) < b_.after)
277 ASSERT (getStart(succ_) < b_.after
278 ,
"seamless segmentation");
280 if (b_.after == getAfter(succ_)) opSucc_ = DROP;
282 if (b_.after < getAfter(succ_)) opSucc_ = TRUNC;
286 if (b_.after == startSucc) opSucc_ = SEAMLESS;
287 else opSucc_ = INS_NOP;
302 POS refPred = pred_, refSucc = succ_;
303 REQUIRE (opPred_ != NIL and opSucc_ != NIL);
307 if (opPred_ == INS_NOP or opPred_ == SEAMLESS)
309 if (opSucc_ == DROP or opSucc_ == TRUNC)
314 POS n = createSeg (insPos, b_.start, b_.after);
318 if (opPred_ == INS_NOP)
319 s = emptySeg (n, getAfter(refPred), b_.start);
321 if (opPred_ == TRUNC)
322 s = cloneSeg (n, getStart(refPred), b_.start, refPred);
325 if (opSucc_ == INS_NOP)
326 emptySeg (insPos, b_.after, getStart(refSucc));
328 if (opSucc_ == TRUNC)
329 cloneSeg (insPos, b_.after, getAfter(refSucc), refSucc);
332 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.