Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
list-diff-detector.hpp
Go to the documentation of this file.
1/*
2 LIST-DIFF-DETECTOR.hpp - language to describe differences in linearised form
3
4 Copyright (C)
5 2015, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
48#ifndef LIB_DIFF_LIST_DIFF_DETECTOR_H
49#define LIB_DIFF_LIST_DIFF_DETECTOR_H
50
51
54#include "lib/iter-adapter.hpp"
55#include "lib/nocopy.hpp"
56
57#include <utility>
58
59
60namespace lib {
61namespace diff{
62
63 using util::unConst;
64 using std::move;
65 using std::swap;
66
67
77 template<class SEQ>
80 {
81 using Val = SEQ::value_type;
83
85 SEQ const& currentData_;
86
87
89
91 class DiffFrame;
92
93
94
95
96 public:
97 explicit
98 DiffDetector(SEQ const& refSeq)
99 : refIdx_(refSeq)
100 , currentData_(refSeq)
101 { }
102
103
108 bool
109 isChanged() const
110 {
111 auto snapshot = refIdx_.begin();
112 for (auto const& elm : currentData_)
113 if (snapshot != refIdx_.end() && elm != *snapshot++)
114 return true;
115
116 return false;
117 }
118
119
122
137 Diff
139 {
140 Idx mark (currentData_);
141 swap (mark, refIdx_); // mark now refers to old reference point
142 return Diff(DiffFrame(refIdx_, move(mark)));
143 }
144 };
145
146
147
148
158 template<class SEQ>
160 {
163 size_t oldHead_=0,
164 newHead_=0;
165
167
169
170
171 public:
172 DiffFrame(Idx& current, Idx&& refPoint)
173 : old_(refPoint)
174 , new_(&current)
175 , currentStep_(establishNextState())
176 { }
177
178
179 /* === Iteration control API for IterStateWrapper === */
180
181 bool
183 {
184 return token.NIL != currentStep_;
185 }
186
187 DiffStep&
188 yield() const
189 {
190 REQUIRE (checkPoint());
191 return unConst(this)->currentStep_;
192 }
193
194 void
196 {
197 currentStep_ = this->establishNextState();
198 }
199
200 private:
203 {
204 if (canPick())
205 {
206 consumeOld();
207 return token.pick (consumeNew());
208 }
209 if (canDelete())
210 return token.del (consumeOld());
211 if (canInsert())
212 return token.ins (consumeNew());
213 if (needFetch())
214 return token.find (consumeNew());
215 if (obsoleted())
216 return token.skip (consumeOld());
217
218 return token.NIL;
219 }
220
221 bool hasOld() const { return oldHead_ < old_.size(); }
222 bool hasNew() const { return newHead_ < new_->size(); }
223 bool canPick() const { return hasOld() && hasNew() && oldElm()==newElm(); }
224 bool canDelete() const { return hasOld() && !new_->contains(oldElm()); }
225 bool canInsert() const { return hasNew() && !old_.contains(newElm()); }
226 bool needFetch() const { return hasNew() && oldHead_ < old_.pos(newElm()); }
227 bool obsoleted() const { return hasOld() && newHead_ > new_->pos(oldElm()); }
228
229 Val const& oldElm() const { return old_.getElement (oldHead_); }
230 Val const& newElm() const { return new_->getElement (newHead_); }
231 Val const& consumeOld() { return old_.getElement (oldHead_++); }
232 Val const& consumeNew() { return new_->getElement (newHead_++); }
233 };
234
235
237 template<class SEQ>
239
240
241
242
243}} // namespace lib::diff
244#endif /*LIB_DIFF_LIST_DIFF_DETECTOR_H*/
Another Lumiera Forward Iterator building block, based on incorporating a state type as »*State Core*...
A diff generation process is built on top of an "old" reference point and a "new" state of the underl...
static ListDiffLanguage< Val > token
allocate static storage for the diff language token builder functions
DiffFrame(Idx &current, Idx &&refPoint)
Detect and describe changes in a monitored data sequence.
ListDiffLanguage< Val >::DiffStep DiffStep
Diff pullUpdate()
Diff generation core operation.
bool isChanged() const
does the current state of the underlying sequence differ from the state embodied into the last refere...
DiffDetector(SEQ const &refSeq)
lib::IterStateWrapper< DiffFrame > Diff
Diff is a iterator to yield a sequence of DiffStep elements.
size_t size() const
bool contains(VAL const &elm) const
VAL const & getElement(size_t i) const
size_t pos(VAL const &elm) const
Any copy and copy construction prohibited.
Definition nocopy.hpp:38
Generic lookup table for a sequence of unique values.
Helper template(s) for creating Lumiera Forward Iterators.
A token language to represent changes in a list of elements.
Implementation namespace for support and library code.
OBJ * unConst(const OBJ *)
shortcut to save some typing when having to define const and non-const variants of member functions
Definition util.hpp:358
Mix-Ins to allow or prohibit various degrees of copying and cloning.
static const DiffStep NIL
fixed "invalid" marker token