Guitar
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 
41 namespace 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;
58  bool conflict;
59  elem csepabegin;
60  elem csepa;
61  elem csepaend;
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
dtl::Diff3::Diff3
Diff3(const sequence &a, const sequence &b, const sequence &c)
Definition: Diff3.hpp:64
dtl::Diff3::joinElemVec
void joinElemVec(elemVec &s1, elemVec &s2) const
Definition: Diff3.hpp:208
dtl::SES_ADD
const edit_t SES_ADD
Definition: variables.hpp:74
dtl::Diff3
Definition: Diff3.hpp:48
dtl::Diff3::isEnd
bool isEnd(const T_iter &end, const T_iter &it) const
Definition: Diff3.hpp:220
dtl::Diff3::Diff3
Diff3()
Definition: Diff3.hpp:63
dtl::Diff3::~Diff3
~Diff3()
Definition: Diff3.hpp:70
dtl::SES_DELETE
const edit_t SES_DELETE
Definition: variables.hpp:72
dtl::Diff3::diff_bc
Diff< elem, sequence, comparator > diff_bc
Definition: Diff3.hpp:57
dtl::SES_COMMON
const edit_t SES_COMMON
Definition: variables.hpp:73
dtl::Diff3::getMergedSequence
sequence getMergedSequence() const
Definition: Diff3.hpp:76
dtl::Ses::getSequence
sesElemVec getSequence() const
Definition: Ses.hpp:119
dtl::Diff3::S
sequence S
Definition: Diff3.hpp:55
dtl::Diff3::dtl_typedefs
dtl_typedefs(elem, sequence) sequence A
dtl::Diff3::isConflict
bool isConflict() const
Definition: Diff3.hpp:72
dtl
Definition: Diff.hpp:41
dtl::Diff3::B
sequence B
Definition: Diff3.hpp:53
dtl::Diff3::conflict
bool conflict
Definition: Diff3.hpp:58
dtl::Diff
Definition: Diff.hpp:48
dtl::Diff3::forwardUntilEnd
void forwardUntilEnd(const T_iter &end, T_iter &it) const
Definition: Diff3.hpp:228
dtl::Diff3::csepabegin
elem csepabegin
Definition: Diff3.hpp:59
dtl::Diff3::compose
void compose()
Definition: Diff3.hpp:108
dtl::Diff3::C
sequence C
Definition: Diff3.hpp:54
dtl::Diff3::diff_ba
Diff< elem, sequence, comparator > diff_ba
Definition: Diff3.hpp:56
dtl::Diff3::merge_
sequence merge_()
Definition: Diff3.hpp:117
dtl::Diff3::csepaend
elem csepaend
Definition: Diff3.hpp:61
dtl::Diff3::addDecentSequence
void addDecentSequence(const sesElemVec_iter &end, sesElemVec_iter &it, elemVec &seq) const
Definition: Diff3.hpp:235
dtl::Diff3::csepa
elem csepa
Definition: Diff3.hpp:60
dtl::Diff3::merge
bool merge()
Definition: Diff3.hpp:83
dtl::Ses
Definition: Ses.hpp:47