// alirow_iter.h // seq1Len >= seq2Len? // CASE 1: // 0 i // seq1: **************------- left1 = 0, len = i // seq2: ---------************** // 0 * // left2 // // CASE 2: // left1 // * // seq1: -----------********** // seq2: **********----------- left2 = 0, len = seq1Len - left1 // i class AlignRowIterator { protected: string *ali; // address of an alignment row with gaps int iA; // current pos in 'ali' - offset; int iS; // current pos in sequence ('ali' with gaps removed) int iL; // ali length public: /** int i; // progress: 0 ...... (seq1Len + seq2Len -1) int left1; int left2; int len; TwoSeqProgress() : i(0), seq1Len(1), seq2Len(1) {}; TwoSeqProgress( int len1, int len2 ) : seq1Len(len1), seq2Len(len2) {} **/ AlignRowIterator() : ali(0), iA(0), iS(0), iL(0) {} AlignRowIterator( string *a ) : ali(a), iA(0), iS(0), iL( (*a).length() ) {} AlignRowIterator& operator= ( string *a ) { ali=a; iA =0; iS=0; iL = (*a).length(); return *this; } AlignRowIterator& operator= ( AlignRowIterator& a ) { ali=a.ali; iA = a.iA; iS=a.iS; iL = a.iL; return *this; } AlignRowIterator& begin() { int i; for( i = 0; i < iL; ++i ) { if( (*ali)[i] != '-' ) break; // skipping gaps } iA = i; iS = 0; return *this; } AlignRowIterator& end() { iA = iL; iS = iL; return *this; } int align_pos() { return iA; } int sequence_pos() { return iS; } int gaps_before() { if( iA < 1 ) return 0; // ------> int i, iG = 0; for( i = iA - 1; i >= 0; --i ) { if( (*ali)[i] != '-' ) break; ++iG; } return iG; } bool operator== ( AlignRowIterator& a ) const { return ( ali == a.ali && iA == a.iA); } bool operator< ( AlignRowIterator& a ) const { return ( iA < a.iA); } int operator* () const { return iA ; } // seq pos AlignRowIterator& operator++() { int i; ++iA; for( i = iA; i < iL; ++i ) { if( (*ali)[i] != '-' ) break; // skipping gaps } if( i < iL ) iA = i; else iA = iL; // end() ++iS; if( iS > iL ) iS = iL; // no more return *this; } /** TwoSeqProgress& operator= ( int i0 ) { // ***** not tested i = i0; // Case 1: if( i < seq1Len ) { left1 = 0; left2 = seq2Len - i - 1; len = i + 1; if( left2 < 0 ) { left1 -= left2; len = seq2Len; left2 = 0; } return *this; // --------------------------------> } // Case 2: // i >= seq1Len: left2 = 0; len = seq1Len + seq2Len - i - 1; left1 = seq1Len - len; if( left1 < 0 ) { left2 = seq2Len - i - 1; len = seq1Len; left1 = 0; } return *this; } bool operator< ( int n) const { return (i < n); } const TwoSeqProgress& operator* () const { return *this ; } TwoSeqProgress& operator++() { i++; if( i < seq1Len ) { left2--; len++; if( left2 < 0 ) { // = -1 // seq2 < seq1 left1 += 1; len = seq2Len; left2 = 0; } return *this; // -----------------------------> } // i >= seq1Len left1++; len--; if( left2 > 0 ) { // = -1 // seq2 > seq1 left2 -= 1; len = seq1Len; left1 = 0; } return *this; } **/ };