NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
Diff3.hpp
Go to the documentation of this file.
1
36/* If you use this library, you must include dtl.hpp only. */
37
38#ifndef DTL_DIFF3_H
39#define DTL_DIFF3_H
40
41namespace dtl {
42
47 template <typename elem, typename sequence = vector< elem >, typename comparator = Compare< elem > >
48 class Diff3
49 {
50 private:
51 dtl_typedefs(elem, sequence)
52 sequence A;
53 sequence B;
54 sequence C;
55 sequence S;
60 elem csepa;
62 public :
63 Diff3 () {}
64 Diff3 (const sequence& a,
65 const sequence& b,
66 const sequence& c) : A(a), B(b), C(c),
67 diff_ba(b, a), diff_bc(b, c),
68 conflict(false) {}
69
70 ~Diff3 () {}
71
72 bool isConflict () const {
73 return conflict;
74 }
75
76 sequence getMergedSequence () const {
77 return S;
78 }
79
83 bool merge () {
84 if (diff_ba.getEditDistance() == 0) { // A == B
85 if (diff_bc.getEditDistance() == 0) { // A == B == C
86 S = B;
87 return true;
88 }
89 S = C;
90 return true;
91 } else { // A != B
92 if (diff_bc.getEditDistance() == 0) { // A != B == C
93 S = A;
94 return true;
95 } else { // A != B != C
96 S = merge_();
97 if (isConflict()) { // conflict occured
98 return false;
99 }
100 }
101 }
102 return true;
103 }
104
108 void compose () {
109 diff_ba.compose();
110 diff_bc.compose();
111 }
112
113 private :
117 sequence merge_ () {
118 elemVec seq;
119 Ses< elem > ses_ba = diff_ba.getSes();
120 Ses< elem > ses_bc = diff_bc.getSes();
121 sesElemVec ses_ba_v = ses_ba.getSequence();
122 sesElemVec ses_bc_v = ses_bc.getSequence();
123 sesElemVec_iter ba_it = ses_ba_v.begin();
124 sesElemVec_iter bc_it = ses_bc_v.begin();
125 sesElemVec_iter ba_end = ses_ba_v.end();
126 sesElemVec_iter bc_end = ses_bc_v.end();
127
128 while (!isEnd(ba_end, ba_it) || !isEnd(bc_end, bc_it)) {
129 while (true) {
130 if (!isEnd(ba_end, ba_it) &&
131 !isEnd(bc_end, bc_it) &&
132 ba_it->first == bc_it->first &&
133 ba_it->second.type == SES_COMMON &&
134 bc_it->second.type == SES_COMMON) {
135 // do nothing
136 } else {
137 break;
138 }
139 if (!isEnd(ba_end, ba_it)) seq.push_back(ba_it->first);
140 else if (!isEnd(bc_end, bc_it)) seq.push_back(bc_it->first);
141 forwardUntilEnd(ba_end, ba_it);
142 forwardUntilEnd(bc_end, bc_it);
143 }
144 if (isEnd(ba_end, ba_it) || isEnd(bc_end, bc_it)) break;
145 if ( ba_it->second.type == SES_COMMON
146 && bc_it->second.type == SES_DELETE) {
147 forwardUntilEnd(ba_end, ba_it);
148 forwardUntilEnd(bc_end, bc_it);
149 } else if (ba_it->second.type == SES_COMMON &&
150 bc_it->second.type == SES_ADD) {
151 seq.push_back(bc_it->first);
152 forwardUntilEnd(bc_end, bc_it);
153 } else if (ba_it->second.type == SES_DELETE &&
154 bc_it->second.type == SES_COMMON) {
155 forwardUntilEnd(ba_end, ba_it);
156 forwardUntilEnd(bc_end, bc_it);
157 } else if (ba_it->second.type == SES_DELETE &&
158 bc_it->second.type == SES_DELETE) {
159 if (ba_it->first == bc_it->first) {
160 forwardUntilEnd(ba_end, ba_it);
161 forwardUntilEnd(bc_end, bc_it);
162 } else {
163 // conflict
164 conflict = true;
165 return B;
166 }
167 } else if (ba_it->second.type == SES_DELETE &&
168 bc_it->second.type == SES_ADD) {
169 // conflict
170 conflict = true;
171 return B;
172 } else if (ba_it->second.type == SES_ADD &&
173 bc_it->second.type == SES_COMMON) {
174 seq.push_back(ba_it->first);
175 forwardUntilEnd(ba_end, ba_it);
176 } else if (ba_it->second.type == SES_ADD &&
177 bc_it->second.type == SES_DELETE) {
178 // conflict
179 conflict = true;
180 return B;
181 } else if (ba_it->second.type == SES_ADD &&
182 bc_it->second.type == SES_ADD) {
183 if (ba_it->first == bc_it->first) {
184 seq.push_back(ba_it->first);
185 forwardUntilEnd(ba_end, ba_it);
186 forwardUntilEnd(bc_end, bc_it);
187 } else {
188 // conflict
189 conflict = true;
190 return B;
191 }
192 }
193 }
194
195 if (isEnd(ba_end, ba_it)) {
196 addDecentSequence(bc_end, bc_it, seq);
197 } else if (isEnd(bc_end, bc_it)) {
198 addDecentSequence(ba_end, ba_it, seq);
199 }
200
201 sequence mergedSeq(seq.begin(), seq.end());
202 return mergedSeq;
203 }
204
208 void inline joinElemVec (elemVec& s1, elemVec& s2) const {
209 if (!s2.empty()) {
210 for (elemVec_iter vit=s2.begin();vit!=s2.end();++vit) {
211 s1.push_back(*vit);
212 }
213 }
214 }
215
219 template <typename T_iter>
220 bool inline isEnd (const T_iter& end, const T_iter& it) const {
221 return it == end ? true : false;
222 }
223
227 template <typename T_iter>
228 void inline forwardUntilEnd (const T_iter& end, T_iter& it) const {
229 if (!isEnd(end, it)) ++it;
230 }
231
235 void inline addDecentSequence (const sesElemVec_iter& end, sesElemVec_iter& it, elemVec& seq) const {
236 while (!isEnd(end, it)) {
237 if (it->second.type == SES_ADD) seq.push_back(it->first);
238 ++it;
239 }
240 }
241
242 };
243}
244
245#endif // DTL_DIFF3_H
sequence getMergedSequence() const
Definition: Diff3.hpp:76
void compose()
Definition: Diff3.hpp:108
elem csepaend
Definition: Diff3.hpp:61
dtl_typedefs(elem, sequence) sequence A
Diff3(const sequence &a, const sequence &b, const sequence &c)
Definition: Diff3.hpp:64
bool conflict
Definition: Diff3.hpp:58
bool merge()
Definition: Diff3.hpp:83
elem csepabegin
Definition: Diff3.hpp:59
bool isEnd(const T_iter &end, const T_iter &it) const
Definition: Diff3.hpp:220
Diff< elem, sequence, comparator > diff_bc
Definition: Diff3.hpp:57
~Diff3()
Definition: Diff3.hpp:70
sequence S
Definition: Diff3.hpp:55
void forwardUntilEnd(const T_iter &end, T_iter &it) const
Definition: Diff3.hpp:228
sequence B
Definition: Diff3.hpp:53
sequence C
Definition: Diff3.hpp:54
void addDecentSequence(const sesElemVec_iter &end, sesElemVec_iter &it, elemVec &seq) const
Definition: Diff3.hpp:235
sequence merge_()
Definition: Diff3.hpp:117
Diff< elem, sequence, comparator > diff_ba
Definition: Diff3.hpp:56
void joinElemVec(elemVec &s1, elemVec &s2) const
Definition: Diff3.hpp:208
bool isConflict() const
Definition: Diff3.hpp:72
elem csepa
Definition: Diff3.hpp:60
Definition: Ses.hpp:48
sesElemVec getSequence() const
Definition: Ses.hpp:119
Definition: Diff.hpp:41
const edit_t SES_ADD
Definition: variables.hpp:74
const edit_t SES_COMMON
Definition: variables.hpp:73
const edit_t SES_DELETE
Definition: variables.hpp:72