00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef DTL_H
00013 #define DTL_H
00014
00015 #include <vector>
00016 #include <list>
00017 #include <string>
00018 #include <algorithm>
00019 #include <iostream>
00020
00026 namespace dtl {
00027
00031 typedef int editType;
00032 const editType SES_DELETE = -2;
00033 const editType SES_COMMON = 0;
00034 const editType SES_ADD = 2;
00035
00039 const std::string SES_MARK_DELETE = "-";
00040 const std::string SES_MARK_COMMON = " ";
00041 const std::string SES_MARK_ADD = "+";
00042
00046 typedef struct eleminfo {
00047 int beforeIdx;
00048 int afterIdx;
00049 editType type;
00050 } elemInfo;
00051
00052 #define SEPARATE_SIZE (3)
00053 #define CONTEXT_SIZE (3)
00054
00058 typedef struct Point {
00059 int x;
00060 int y;
00061 int k;
00062 } P;
00063
00067 const unsigned int MAX_CORDINATES_SIZE = 2000000;
00068
00069 typedef std::vector<int> editPath;
00070 typedef std::vector<P> editPathCordinates;
00071
00075 template <typename sesElem>
00076
00077 struct uniHunk {
00078 int a, b, c, d;
00079 std::vector<sesElem> common[2];
00080 std::vector<sesElem> change;
00081 int inc_dec_count;
00082 };
00083
00084
00088 template <typename sesElem>
00089 class PrintCommon
00090 {
00091 public :
00092 void operator() (sesElem se) {
00093 std::cout << SES_MARK_COMMON << se.first << std::endl;
00094 }
00095 };
00096
00097 template <typename sesElem>
00098 class PrintChange
00099 {
00100 public :
00101 void operator() (sesElem se) {
00102 switch (se.second.type) {
00103 case SES_ADD:
00104 std::cout << SES_MARK_ADD << se.first << std::endl;
00105 break;
00106 case SES_DELETE:
00107 std::cout << SES_MARK_DELETE << se.first << std::endl;
00108 break;
00109 case SES_COMMON:
00110 std::cout << SES_MARK_COMMON << se.first << std::endl;
00111 break;
00112 }
00113 }
00114 };
00115
00116 template <typename sesElem>
00117 class PrintUniHunk
00118 {
00119 public :
00120 void operator() (uniHunk< sesElem > hunk) {
00121
00122 std::cout << "@@"
00123 << " -" << hunk.a << "," << hunk.b
00124 << " +" << hunk.c << "," << hunk.d
00125 << " @@" << std::endl;
00126
00127 std::for_each(hunk.common[0].begin(), hunk.common[0].end(), PrintCommon< sesElem >());
00128 std::for_each(hunk.change.begin(), hunk.change.end(), PrintChange< sesElem >());
00129 std::for_each(hunk.common[1].begin(), hunk.common[1].end(), PrintCommon< sesElem >());
00130 }
00131 };
00132
00136 template <typename elem>
00137 class Sequence
00138 {
00139 public :
00140 typedef std::vector<elem> elemVec;
00141 Sequence () {}
00142 virtual ~Sequence () {}
00143
00144 elemVec getSequence () const {
00145 return sequence;
00146 }
00147 void addSequence (elem e) {
00148 sequence.push_back(e);
00149 }
00150 protected :
00151 elemVec sequence;
00152 };
00153
00154 template <typename elem>
00155 struct idxLcs {
00156 elem e;
00157 int a_idx, b_idx;
00158 };
00159
00163 template <typename elem>
00164 class Lcs : public Sequence<elem>
00165 {
00166 private :
00167 typedef std::vector< idxLcs<elem> > lcsSequence;
00168 lcsSequence lcsSeq;
00169 public :
00170 Lcs () {}
00171 ~Lcs () {}
00172 void addLcsSequence (elem e, int a_idx, int b_idx) {
00173 idxLcs<elem> ie;
00174 ie.e = e;
00175 ie.a_idx = a_idx;
00176 ie.b_idx = b_idx;
00177 lcsSeq.push_back(ie);
00178 }
00179 lcsSequence getLcsSequence () const {
00180 return lcsSeq;
00181 }
00182 };
00183
00187 template <typename elem>
00188 class Ses : public Sequence<elem>
00189 {
00190 private :
00191 typedef std::pair<elem, elemInfo> sesElem;
00192 typedef std::vector< sesElem > sesElemVec;
00193 public :
00194
00195 Ses () : onlyAdd(true), onlyDelete(true), onlyCopy(true) { }
00196 ~Ses () {}
00197
00198 bool isOnlyAdd () const {
00199 return onlyAdd;
00200 }
00201
00202 bool isOnlyDelete () const {
00203 return onlyDelete;
00204 }
00205
00206 bool isOnlyCopy () const {
00207 return onlyCopy;
00208 }
00209
00210 bool isOnlyOneOperation () const {
00211 return isOnlyAdd() || isOnlyAdd() || isOnlyCopy();
00212 }
00213
00214 bool isChange () const {
00215 return !onlyCopy;
00216 }
00217
00218 using Sequence<elem>::addSequence;
00219 void addSequence (elem e, int beforeIdx, int afterIdx, editType type) {
00220 elemInfo info;
00221 info.beforeIdx = beforeIdx;
00222 info.afterIdx = afterIdx;
00223 info.type = type;
00224 sesElem pe(e, info);
00225 sequence.push_back(pe);
00226 switch (type) {
00227 case SES_DELETE:
00228 onlyCopy = false;
00229 onlyAdd = false;
00230 break;
00231 case SES_COMMON:
00232 onlyAdd = false;
00233 onlyDelete = false;
00234 break;
00235 case SES_ADD:
00236 onlyDelete = false;
00237 onlyCopy = false;
00238 break;
00239 }
00240 }
00241
00242 sesElemVec getSequence () const {
00243 return sequence;
00244 }
00245 private :
00246 sesElemVec sequence;
00247 bool onlyAdd;
00248 bool onlyDelete;
00249 bool onlyCopy;
00250 };
00251
00256 template <typename elem, typename sequence>
00257 class Diff
00258 {
00259 typedef std::pair<elem, elemInfo> sesElem;
00260 typedef std::vector< sesElem > sesElemVec;
00261 typedef std::vector< uniHunk< sesElem > > uniHunkVec;
00262 typedef std::list< elem > elemList;
00263 private :
00264 sequence A;
00265 sequence B;
00266 int M;
00267 int N;
00268 int delta;
00269 int offset;
00270 int *fp;
00271 int editDistance;
00272 Lcs<elem> lcs;
00273 Ses<elem> ses;
00274 editPath path;
00275 editPathCordinates pathCordinates;
00276 bool reverse;
00277 bool huge;
00278 bool unserious;
00279 bool onlyEditDistance;
00280 uniHunkVec uniHunks;
00281 public :
00282 Diff (sequence& a, sequence& b) : A(a), B(b) {
00283 init();
00284 }
00285
00286 ~Diff() {}
00287
00288 int getEditDistance () const {
00289 return editDistance;
00290 }
00291
00292 Lcs<elem> getLcs () const {
00293 return lcs;
00294 }
00295
00296 Ses<elem> getSes () const {
00297 return ses;
00298 }
00299
00300 uniHunkVec getUniHunks () const {
00301 return uniHunks;
00302 }
00303
00304 bool isReverse () const {
00305 return reverse;
00306 }
00307
00308 bool isHuge () const {
00309 return huge;
00310 }
00311
00312 void onHuge () {
00313 this->huge = true;
00314 }
00315
00316 void offHuge () {
00317 this->huge = false;
00318 }
00319
00320 bool isUnserious () const {
00321 return unserious;
00322 }
00323
00324 void onUnserious () {
00325 this->unserious = true;
00326 }
00327
00328 void offUnserious () {
00329 this->unserious = false;
00330 }
00331
00332 void onOnlyEditDistance () {
00333 this->onlyEditDistance = true;
00334 }
00335
00339 sequence uniPatch (sequence seq) {
00340 elemList seqLst(seq.begin(), seq.end());
00341 sesElemVec shunk;
00342 typename uniHunkVec::iterator it;
00343 typename sesElemVec::iterator vsesIt;
00344 typename elemList::iterator lstIt = seqLst.begin();
00345 typename elemList::iterator lstIt_t = seqLst.begin();;
00346 typename sequence::iterator cit = seq.begin();
00347 int inc_dec_total = 0;
00348 int seq_lnum = 1;
00349 int longer_seq_lnum = 1;
00350 int loop = 0;
00351 for (it=uniHunks.begin();it!=uniHunks.end();++it, ++loop) {
00352 joinSesVec(shunk, it->common[0]);
00353 joinSesVec(shunk, it->change);
00354 joinSesVec(shunk, it->common[1]);
00355 it->a += inc_dec_total;
00356 if (loop != 0) ++lstIt_t;
00357 lstIt = lstIt_t;
00358 while (seq_lnum++ < it->a && longer_seq_lnum++ < N) {
00359 ++cit;
00360 if (lstIt != seqLst.end()) ++lstIt;
00361 }
00362 lstIt_t = lstIt;
00363 inc_dec_total += it->inc_dec_count;
00364 vsesIt = shunk.begin();
00365 while (vsesIt!=shunk.end()) {
00366 switch (vsesIt->second.type) {
00367 case SES_ADD :
00368 seqLst.insert(lstIt, vsesIt->first);
00369 break;
00370 case SES_DELETE :
00371 if (lstIt != seqLst.end()) {
00372 lstIt = seqLst.erase(lstIt);
00373 }
00374 break;
00375 case SES_COMMON :
00376 if (lstIt != seqLst.end()) {
00377 ++lstIt;
00378 }
00379 break;
00380 default :
00381 break;
00382 }
00383 ++vsesIt;
00384 }
00385 shunk.clear();
00386 }
00387
00388 sequence patchedSeq(seqLst.begin(), seqLst.end());
00389 return patchedSeq;
00390 }
00391
00395 sequence patch (sequence seq) const {
00396 sesElemVec sesSeq = ses.getSequence();
00397 elemList seqLst(seq.begin(), seq.end());
00398 typename elemList::iterator lstIt = seqLst.begin();
00399 typename sesElemVec::iterator sesIt;
00400 for (sesIt=sesSeq.begin();sesIt!=sesSeq.end();++sesIt) {
00401 switch (sesIt->second.type) {
00402 case SES_ADD :
00403 seqLst.insert(lstIt, sesIt->first);
00404 break;
00405 case SES_DELETE :
00406 lstIt = seqLst.erase(lstIt);
00407 break;
00408 case SES_COMMON :
00409 ++lstIt;
00410 break;
00411 default :
00412
00413 break;
00414 }
00415 }
00416 sequence patchedSeq(seqLst.begin(), seqLst.end());
00417 return patchedSeq;
00418 }
00419
00425 void compose() {
00426
00427 if (isHuge()) pathCordinates.reserve(MAX_CORDINATES_SIZE + 50000);
00428
00429 int p = -1;
00430 int k;
00431 int size = M + N + 3;
00432 fp = new int[size];
00433 std::fill(&fp[0], &fp[size], -1);
00434 path = editPath(size);
00435 std::fill(path.begin(), path.end(), -1);
00436 ONP:
00437 do {
00438 ++p;
00439 for (k=-p;k<=delta-1;++k) {
00440 fp[k+offset] = snake(k, fp[k-1+offset]+1, fp[k+1+offset]);
00441 }
00442 for (k=delta+p;k>=delta+1;--k) {
00443 fp[k+offset] = snake(k, fp[k-1+offset]+1, fp[k+1+offset]);
00444 }
00445 fp[delta+offset] = snake(delta, fp[delta-1+offset]+1, fp[delta+1+offset]);
00446 } while (fp[delta+offset] != N && pathCordinates.size() < MAX_CORDINATES_SIZE);
00447
00448 editDistance += delta + 2 * p;
00449 int r = path[delta+offset];
00450 P cordinate;
00451 editPathCordinates epc(0);
00452
00453
00454 if (onlyEditDistance) return;
00455
00456 while(r != -1){
00457 cordinate.x = pathCordinates[r].x;
00458 cordinate.y = pathCordinates[r].y;
00459 epc.push_back(cordinate);
00460 r = pathCordinates[r].k;
00461 }
00462
00463
00464 if (!recordSequence(epc)) {
00465 pathCordinates.resize(0);
00466 epc.resize(0);
00467 p = -1;
00468 goto ONP;
00469 }
00470 delete[] this->fp;
00471 }
00472
00476 void printUnifiedFormat () {
00477 std::for_each(uniHunks.begin(), uniHunks.end(), PrintUniHunk< sesElem >());
00478 }
00479
00483 void composeUnifiedHunks () {
00484 sesElemVec common[2];
00485 sesElemVec change;
00486 sesElemVec ses_v = ses.getSequence();
00487 typename sesElemVec::iterator it;
00488 int l_cnt = 1;
00489 int length = std::distance(ses_v.begin(), ses_v.end());
00490 int middle = 0;
00491 bool isMiddle, isAfter;
00492 isMiddle = isAfter = false;
00493 elem e;
00494 elemInfo einfo;
00495 int a, b, c, d;
00496 int inc_dec_count = 0;
00497 a = b = c = d = 0;
00498 uniHunk<sesElem> hunk;
00499 sesElemVec adds;
00500 sesElemVec deletes;
00501
00502 for (it=ses_v.begin();it!=ses_v.end();++it, ++l_cnt) {
00503 e = it->first;
00504 einfo = it->second;
00505 switch (einfo.type) {
00506 case SES_ADD :
00507 middle = 0;
00508 ++inc_dec_count;
00509 adds.push_back(*it);
00510 if (!isMiddle) isMiddle = true;
00511 if (isMiddle) ++d;
00512 if (l_cnt >= length) {
00513 joinSesVec(change, deletes);
00514 joinSesVec(change, adds);
00515 isAfter = true;
00516 }
00517 break;
00518 case SES_DELETE :
00519 middle = 0;
00520 --inc_dec_count;
00521 deletes.push_back(*it);
00522 if (!isMiddle) isMiddle = true;
00523 if (isMiddle) ++b;
00524 if (l_cnt >= length) {
00525 joinSesVec(change, deletes);
00526 joinSesVec(change, adds);
00527 isAfter = true;
00528 }
00529 break;
00530 case SES_COMMON :
00531 ++b;++d;
00532 if (common[1].empty() && adds.empty() && deletes.empty() && change.empty()) {
00533 if (common[0].size() < CONTEXT_SIZE) {
00534 if (a == 0 && c == 0) {
00535 a = einfo.beforeIdx;
00536 c = einfo.afterIdx;
00537 }
00538 common[0].push_back(*it);
00539 } else {
00540 std::rotate(common[0].begin(), common[0].begin() + 1, common[0].end());
00541 common[0].pop_back();
00542 common[0].push_back(*it);
00543 ++a;++c;
00544 --b;--d;
00545 }
00546 }
00547 if (isMiddle && !isAfter) {
00548 ++middle;
00549 typename sesElemVec::iterator vit;
00550 joinSesVec(change, deletes);
00551 joinSesVec(change, adds);
00552 change.push_back(*it);
00553 if (middle >= SEPARATE_SIZE || l_cnt >= length) {
00554 isAfter = true;
00555 }
00556 adds.clear();
00557 deletes.clear();
00558 }
00559 break;
00560 default :
00561
00562 break;
00563 }
00564
00565 if (isAfter && !change.empty()) {
00566 typename sesElemVec::iterator cit = it;
00567 int cnt = 0;
00568 for (int i=0;i<SEPARATE_SIZE;++i, ++cit) {
00569 if (cit->second.type == SES_COMMON) {
00570 ++cnt;
00571 }
00572 }
00573 if (cnt < SEPARATE_SIZE && l_cnt < length) {
00574 middle = 0;
00575 isAfter = false;
00576 continue;
00577 }
00578 if (common[0].size() >= SEPARATE_SIZE) {
00579 int c0size = common[0].size();
00580 std::rotate(common[0].begin(),
00581 common[0].begin() + c0size - SEPARATE_SIZE,
00582 common[0].end());
00583 for (int i=0;i<c0size-SEPARATE_SIZE;++i) {
00584 common[0].pop_back();
00585 }
00586 a += c0size - SEPARATE_SIZE;
00587 c += c0size - SEPARATE_SIZE;
00588 }
00589 if (a == 0) ++a;
00590 if (c == 0) ++c;
00591 if (isReverse()) std::swap(a, c);
00592 hunk.a = a;hunk.b = b;hunk.c = c;hunk.d = d;
00593 hunk.common[0] = common[0];
00594 hunk.change = change;
00595 hunk.common[1] = common[1];
00596 hunk.inc_dec_count = inc_dec_count;
00597 uniHunks.push_back(hunk);
00598 isMiddle = false;
00599 isAfter = false;
00600 common[0].clear();
00601 common[1].clear();
00602 adds.clear();
00603 deletes.clear();
00604 change.clear();
00605 a = b = c = d = middle = inc_dec_count = 0;
00606 }
00607 }
00608 }
00609 private :
00610 void init () {
00611 M = std::distance(A.begin(), A.end());
00612 N = std::distance(B.begin(), B.end());
00613 if (M < N) {
00614 reverse = false;
00615 } else {
00616 std::swap(A, B);
00617 std::swap(M, N);
00618 reverse = true;
00619 }
00620 editDistance = 0;
00621 delta = N - M;
00622 offset = M + 1;
00623 huge = false;
00624 unserious = false;
00625 onlyEditDistance = false;
00626 fp = NULL;
00627 }
00628
00629 int snake(int k, int above, int below) {
00630 int r;
00631 if (above > below) {
00632 r = path[k-1+offset];
00633 } else {
00634 r = path[k+1+offset];
00635 }
00636
00637 int y = std::max(above, below);
00638 int x = y - k;
00639 while (x < M && y < N && A[x] == B[y]) {
00640 ++x;++y;
00641 }
00642
00643 path[k+offset] = pathCordinates.size();
00644 if (!onlyEditDistance) {
00645 P p;
00646 p.x = x;p.y = y;p.k = r;
00647 pathCordinates.push_back(p);
00648 }
00649 return y;
00650 }
00651
00652 bool recordSequence (editPathCordinates& v) {
00653 typename sequence::const_iterator x(A.begin());
00654 typename sequence::const_iterator y(B.begin());
00655 int x_idx, y_idx;
00656 int px_idx, py_idx;
00657 int size = v.size() - 1;
00658 x_idx = y_idx = 1;
00659 px_idx = py_idx = 0;
00660 for (int i=size;i>=0;--i) {
00661 while(px_idx < v[i].x || py_idx < v[i].y) {
00662 if (v[i].y - v[i].x > py_idx - px_idx) {
00663 if (!isReverse()) {
00664 ses.addSequence(*y, y_idx, 0, SES_ADD);
00665 } else {
00666 ses.addSequence(*y, y_idx, 0, SES_DELETE);
00667 }
00668 ++y;
00669 ++y_idx;
00670 ++py_idx;
00671 } else if (v[i].y - v[i].x < py_idx - px_idx) {
00672 if (!isReverse()) {
00673 ses.addSequence(*x, x_idx, 0, SES_DELETE);
00674 } else {
00675 ses.addSequence(*x, x_idx, 0, SES_ADD);
00676 }
00677 ++x;
00678 ++x_idx;
00679 ++px_idx;
00680 } else {
00681 lcs.addSequence(*x);
00682 lcs.addLcsSequence(*x, x_idx, y_idx);
00683 ses.addSequence(*x, x_idx, y_idx, SES_COMMON);
00684 ++x;
00685 ++y;
00686 ++x_idx;
00687 ++y_idx;
00688 ++px_idx;
00689 ++py_idx;
00690 }
00691 }
00692 }
00693
00694 if (x_idx > M && y_idx > N) {
00695
00696 } else {
00697
00698 if (isUnserious()) {
00699 if (!isReverse()) {
00700 recordOddSequence(x_idx, M, x, SES_DELETE);
00701 recordOddSequence(y_idx, N, y, SES_ADD);
00702 } else {
00703 recordOddSequence(x_idx, M, x, SES_ADD);
00704 recordOddSequence(y_idx, N, y, SES_DELETE);
00705 }
00706 return true;
00707 }
00708
00709
00710 sequence A_(A.begin() + x_idx - 1, A.end());
00711 sequence B_(B.begin() + y_idx - 1, B.end());
00712 A = A_;
00713 B = B_;
00714 M = std::distance(A.begin(), A.end());
00715 N = std::distance(B.begin(), B.end());
00716 delta = N - M;
00717 offset = M + 1;
00718 int size = M + N + 3;
00719 delete[] fp;
00720 fp = new int[size];
00721 std::fill(&fp[0], &fp[size], -1);
00722 std::fill(path.begin(), path.end(), -1);
00723 return false;
00724 }
00725 return true;
00726 }
00727
00728 void recordOddSequence (int idx, int length, typename sequence::const_iterator it, const editType et) {
00729 while(idx < length){
00730 ses.addSequence(*it, idx, 0, et);
00731 ++it;
00732 ++idx;
00733 ++editDistance;
00734 }
00735 ses.addSequence(*it, idx, 0, et);
00736 ++editDistance;
00737 }
00738
00739 void joinSesVec (sesElemVec& s1, sesElemVec& s2) const {
00740 typename sesElemVec::iterator vit;
00741 if (!s2.empty()) {
00742 for (vit=s2.begin();vit!=s2.end();++vit) {
00743 s1.push_back(*vit);
00744 }
00745 }
00746 }
00747
00748 };
00749
00754 template <typename elem, typename sequence>
00755 class Diff3
00756 {
00757 typedef std::pair< elem, elemInfo > sesElem;
00758 typedef std::vector< sesElem > sesElemVec;
00759 typedef std::vector< elem > elemVec;
00760 private:
00761 sequence A;
00762 sequence B;
00763 sequence C;
00764 sequence S;
00765 Diff<elem, sequence> diff_ba;
00766 Diff<elem, sequence> diff_bc;
00767 bool conflict;
00768 elem csepabegin;
00769 elem csepa1;
00770 elem csepa2;
00771 elem csepaend;
00772 public :
00773 Diff3 (sequence& a, sequence& b, sequence& c) : A(a), B(b), C(c),
00774 diff_ba(b, a), diff_bc(b, c),
00775 conflict(false) {}
00776
00777 ~Diff3 () {}
00778
00779 bool isConflict () const {
00780 return conflict;
00781 }
00782
00783 void setConflictSeparators (elem begin, elem sepa1, elem sepa2, elem end) {
00784 csepabegin = begin;
00785 csepa1 = sepa1;
00786 csepa2 = sepa2;
00787 csepaend = end;
00788 }
00789
00790 sequence getMergedSequence () {
00791 return S;
00792 }
00793
00794
00795 bool merge () {
00796 if (diff_ba.getEditDistance() == 0) {
00797 if (diff_bc.getEditDistance() == 0) {
00798 S = B;
00799 return true;
00800 }
00801 S = C;
00802 return true;
00803 } else {
00804 if (diff_bc.getEditDistance() == 0) {
00805 S = A;
00806 return true;
00807 } else {
00808 S = merge_();
00809 if (isConflict()) {
00810 return false;
00811 }
00812 }
00813 }
00814 return true;
00815 }
00816
00817 void compose () {
00818 diff_ba.compose();
00819 diff_bc.compose();
00820 }
00821
00822 private :
00823 sequence merge_ () {
00824 elemVec seq;
00825 Ses<elem> ses_ba = diff_ba.getSes();
00826 Ses<elem> ses_bc = diff_bc.getSes();
00827 sesElemVec ses_ba_v = ses_ba.getSequence();
00828 sesElemVec ses_bc_v = ses_bc.getSequence();
00829 typename sesElemVec::iterator ba_it = ses_ba_v.begin();
00830 typename sesElemVec::iterator bc_it = ses_bc_v.begin();
00831 bool is_ba_end = false;
00832 bool is_bc_end = false;
00833 while (ba_it != ses_ba_v.end() || bc_it != ses_bc_v.end()) {
00834 setEndFlag(ses_ba_v, ba_it, is_ba_end);
00835 setEndFlag(ses_bc_v, bc_it, is_bc_end);
00836 if (is_ba_end || is_bc_end) break;
00837 while (true) {
00838 if (ba_it != ses_ba_v.end()
00839 && bc_it != ses_bc_v.end()
00840 && ba_it->first == bc_it->first
00841 && ba_it->second.type == SES_COMMON
00842 && bc_it->second.type == SES_COMMON) {
00843
00844 } else {
00845 break;
00846 }
00847 if (ba_it != ses_ba_v.end()) seq.push_back(ba_it->first);
00848 else if (bc_it != ses_bc_v.end()) seq.push_back(bc_it->first);
00849 forwardUntilEnd(ses_ba_v, ba_it);
00850 forwardUntilEnd(ses_bc_v, bc_it);
00851 }
00852 setEndFlag(ses_ba_v, ba_it, is_ba_end);
00853 setEndFlag(ses_bc_v, bc_it, is_bc_end);
00854 if (is_ba_end || is_bc_end) break;
00855 if (ba_it->second.type == SES_COMMON && bc_it->second.type == SES_DELETE) {
00856 forwardUntilEnd(ses_ba_v, ba_it);
00857 forwardUntilEnd(ses_bc_v, bc_it);
00858 } else if (ba_it->second.type == SES_COMMON && bc_it->second.type == SES_ADD) {
00859 seq.push_back(bc_it->first);
00860 forwardUntilEnd(ses_bc_v, bc_it);
00861 } else if (ba_it->second.type == SES_DELETE && bc_it->second.type == SES_COMMON) {
00862 forwardUntilEnd(ses_ba_v, ba_it);
00863 forwardUntilEnd(ses_bc_v, bc_it);
00864 } else if (ba_it->second.type == SES_DELETE && bc_it->second.type == SES_DELETE) {
00865 if (ba_it->first == bc_it->first) {
00866 forwardUntilEnd(ses_ba_v, ba_it);
00867 forwardUntilEnd(ses_bc_v, bc_it);
00868 } else {
00869
00870 conflict = true;
00871 return B;
00872 }
00873 } else if (ba_it->second.type == SES_DELETE && bc_it->second.type == SES_ADD) {
00874
00875 conflict = true;
00876 return B;
00877 } else if (ba_it->second.type == SES_ADD && bc_it->second.type == SES_COMMON) {
00878 seq.push_back(ba_it->first);
00879 forwardUntilEnd(ses_ba_v, ba_it);
00880 } else if (ba_it->second.type == SES_ADD && bc_it->second.type == SES_DELETE) {
00881
00882 conflict = true;
00883 return B;
00884 } else if (ba_it->second.type == SES_ADD && bc_it->second.type == SES_ADD) {
00885 if (ba_it->first == bc_it->first) {
00886 seq.push_back(ba_it->first);
00887 forwardUntilEnd(ses_ba_v, ba_it);
00888 forwardUntilEnd(ses_bc_v, bc_it);
00889 } else {
00890
00891 conflict = true;
00892 return B;
00893 }
00894 }
00895 }
00896
00897 if (is_ba_end) {
00898 addDecentSequence(ses_bc_v, bc_it, seq);
00899 } else if (is_bc_end) {
00900 addDecentSequence(ses_ba_v, ba_it, seq);
00901 }
00902
00903 sequence mergedSeq(seq.begin(), seq.end());
00904 return mergedSeq;
00905 }
00906
00907 void forwardUntilEnd (sesElemVec& v, typename sesElemVec::iterator& it) const {
00908 if (it != v.end()) ++it;
00909 }
00910
00911 void setEndFlag (sesElemVec& v, typename sesElemVec::iterator& it, bool& b) const {
00912 if (it == v.end()) b = true;
00913 }
00914
00915 void addDecentSequence (sesElemVec& v, typename sesElemVec::iterator& it, elemVec& seq) const {
00916 while (it != v.end()) {
00917 if (it->second.type == SES_ADD) seq.push_back(it->first);
00918 ++it;
00919 }
00920 }
00921
00922 };
00923 }
00924
00925 #endif // DTL_H