1 // ==========================================================================
2 //                 SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2018, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 //       notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above copyright
13 //       notice, this list of conditions and the following disclaimer in the
14 //       documentation and/or other materials provided with the distribution.
15 //     * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 //       its contributors may be used to endorse or promote products derived
17 //       from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 //  Author: Andreas Gogol-Doering <andreas.doering@mdc-berlin.de>
33 // ==========================================================================
34 
35 #ifndef SEQAN_HEADER_ALIGN_ITERATOR_BASE_H
36 #define SEQAN_HEADER_ALIGN_ITERATOR_BASE_H
37 
38 namespace seqan
39 {
40 
41 //////////////////////////////////////////////////////////////////////////////
42 // Align Iterator for Gaps alignment
43 //////////////////////////////////////////////////////////////////////////////
44 
45 // TODO(holtgrew): Extend class Iter?
46 /*!
47  * @class AlignColIterator
48  * @extends Iter
49  * @headerfile <seqan/align.h>
50  * @brief Iterator for alignment columns.
51  *
52  * @signature template <typename TAlign, typename TSpec>
53  *            class Iter<TAlign, AlignColIterator<TSpec> >;
54  *
55  * @tparam TAlign Align object to iterate columns of.
56  * @tparam TSpec  Tag for specializing the class further.
57  */
58 
59 template <typename TAlign, typename TSpec>
60 class Iter<TAlign, AlignColIterator<TSpec> >
61 {
62 public:
63     typedef typename Rows<TAlign>::Type TRows;
64     typedef typename Row<TAlign>::Type TRow;
65     typedef typename Iterator<TRow, Standard>::Type TRowIterator;
66     typedef typename Position<TRow>::Type TRowPosition;
67     typedef String<TRowIterator> TIterators;
68 
69     TAlign * data_host;
70     TIterators data_iterators;
71 
72 public:
Iter()73     Iter()
74     {
75     }
Iter(TAlign & _align)76     Iter(TAlign & _align):
77         data_host(& _align)
78     {
79         typename Position<TRows>::Type _i = length(rows(_align));
80         resize(data_iterators, _i, Exact());
81     }
Iter(TAlign & _align,TRowPosition _pos)82     Iter(TAlign & _align, TRowPosition _pos):
83         data_host(& _align)
84     {
85         typename Position<TRows>::Type _i = length(rows(_align));
86         resize(data_iterators, _i, Exact());
87 
88         while (_i > 0)
89         {
90             --_i;
91             data_iterators[_i] = iter(row(_align, _i), _pos);
92         }
93     }
Iter(Iter const & _other)94     Iter(Iter const & _other):
95         data_host(_other.data_host),
96         data_iterators(_other.data_iterators)
97     {
98     }
~Iter()99     ~Iter()
100     {
101     }
102 
103     Iter const &
104     operator = (Iter const & _other)
105     {
106         data_host = _other.data_host;
107         data_iterators = _other.data_iterators;
108         return *this;
109     }
110 //____________________________________________________________________________
111 };
112 
113 //////////////////////////////////////////////////////////////////////////////
114 
115 // TODO(holtgrew); Document as dox/hosted?
116 
117 template <typename TAlign, typename TSpec>
118 inline TAlign &
host(Iter<TAlign,AlignColIterator<TSpec>> & me)119 host(Iter<TAlign, AlignColIterator<TSpec> > & me)
120 {
121     return *me.data_host;
122 }
123 template <typename TAlign, typename TSpec>
124 inline TAlign &
host(Iter<TAlign,AlignColIterator<TSpec>> const & me)125 host(Iter<TAlign, AlignColIterator<TSpec> > const & me)
126 {
127     return *me.data_host;
128 }
129 
130 //////////////////////////////////////////////////////////////////////////////
131 
132 template <typename TAlign, typename TSpec>
133 inline void
setHost(Iter<TAlign,AlignColIterator<TSpec>> & me,TAlign & _host)134 setHost(Iter<TAlign, AlignColIterator<TSpec> > & me, TAlign & _host)
135 {
136     me.data_host = & _host;
137 }
138 
139 //////////////////////////////////////////////////////////////////////////////
140 
141 template <typename TAlign, typename TSpec>
142 inline typename Cols<TAlign>::Type
container(Iter<TAlign,AlignColIterator<TSpec>> & me)143 container(Iter<TAlign, AlignColIterator<TSpec> > & me)
144 {
145     return cols(*me.data_host);
146 }
147 template <typename TAlign, typename TSpec>
148 inline typename Cols<TAlign>::Type
container(Iter<TAlign,AlignColIterator<TSpec>> const & me)149 container(Iter<TAlign, AlignColIterator<TSpec> > const & me)
150 {
151     return cols(*me.data_host);
152 }
153 
154 //////////////////////////////////////////////////////////////////////////////
155 
156 template <typename TAlign, typename TSpec>
157 inline void
goNext(Iter<TAlign,AlignColIterator<TSpec>> & me)158 goNext(Iter<TAlign, AlignColIterator<TSpec> > & me)
159 {
160     typedef typename Row<TAlign>::Type TRow;
161     typedef typename Iterator<TRow, Standard>::Type TRowIterator;
162     typedef String<TRowIterator> TIterators;
163     typedef typename Iterator<TIterators, Standard>::Type TIteratorsIterator;
164 
165     TIteratorsIterator _it = begin(me.data_iterators);
166     TIteratorsIterator _it_end = end(me.data_iterators);
167 
168     while (_it != _it_end)
169     {
170         goNext(*_it);
171         ++_it;
172     }
173 }
174 //____________________________________________________________________________
175 
176 template <typename TAlign, typename TSpec>
177 inline Iter<TAlign, AlignColIterator<TSpec> > &
178 operator ++(Iter<TAlign, AlignColIterator<TSpec> > & me)
179 {
180     goNext(me);
181     return me;
182 }
183 //____________________________________________________________________________
184 
185 template <typename TAlign, typename TSpec>
186 inline Iter<TAlign, AlignColIterator<TSpec> >
187 operator ++(Iter<TAlign, AlignColIterator<TSpec> > & me, int)
188 {
189     Iter<TAlign, AlignColIterator<TSpec> > ret = me;
190     goNext(me);
191     return ret;
192 }
193 
194 //////////////////////////////////////////////////////////////////////////////
195 
196 template <typename TAlign, typename TSpec>
197 inline void
goPrevious(Iter<TAlign,AlignColIterator<TSpec>> & me)198 goPrevious(Iter<TAlign, AlignColIterator<TSpec> > & me)
199 {
200     typedef typename Row<TAlign>::Type TRow;
201     typedef typename Iterator<TRow, Standard>::Type TRowIterator;
202     typedef String<TRowIterator> TIterators;
203     typedef typename Iterator<TIterators, Standard>::Type TIteratorsIterator;
204 
205     TIteratorsIterator _it = begin(me.data_iterators);
206     TIteratorsIterator _it_end = end(me.data_iterators);
207 
208     while (_it != _it_end)
209     {
210         goPrevious(*_it);
211         ++_it;
212     }
213 }
214 //____________________________________________________________________________
215 
216 template <typename TAlign, typename TSpec>
217 inline Iter<TAlign, AlignColIterator<TSpec> > &
218 operator --(Iter<TAlign, AlignColIterator<TSpec> > & me)
219 {
220     goPrevious(me);
221     return me;
222 }
223 //____________________________________________________________________________
224 
225 template <typename TAlign, typename TSpec>
226 inline Iter<TAlign, AlignColIterator<TSpec> >
227 operator --(Iter<TAlign, AlignColIterator<TSpec> > & me, int)
228 {
229     Iter<TAlign, AlignColIterator<TSpec> > ret = me;
230     goPrevious(me);
231     return ret;
232 }
233 
234 //////////////////////////////////////////////////////////////////////////////
235 
236 template <typename TAlign1, typename TAlign2, typename TSpec>
237 inline bool
238 operator ==(Iter<TAlign1, AlignColIterator<TSpec> > & _left,
239             Iter<TAlign2, AlignColIterator<TSpec> > & _right)
240 {
241     return getValue(_left.data_iterators, 0) == getValue(_right.data_iterators, 0);
242 }
243 template <typename TAlign1, typename TAlign2, typename TSpec>
244 inline bool
245 operator ==(Iter<TAlign1, AlignColIterator<TSpec> > const & _left,
246             Iter<TAlign2, AlignColIterator<TSpec> > & _right)
247 {
248     return value(_left.data_iterators, 0) == value(_right.data_iterators, 0);
249 }
250 template <typename TAlign1, typename TAlign2, typename TSpec>
251 inline bool
252 operator ==(Iter<TAlign1, AlignColIterator<TSpec> > & _left,
253             Iter<TAlign2, AlignColIterator<TSpec> > const & _right)
254 {
255     return value(_left.data_iterators, 0) == value(_right.data_iterators, 0);
256 }
257 template <typename TAlign1, typename TAlign2, typename TSpec>
258 inline bool
259 operator ==(Iter<TAlign1, AlignColIterator<TSpec> > const & _left,
260             Iter<TAlign2, AlignColIterator<TSpec> > const & _right)
261 {
262     return value(_left.data_iterators, 0) == value(_right.data_iterators, 0);
263 }
264 
265 //////////////////////////////////////////////////////////////////////////////
266 
267 template <typename TAlign1, typename TAlign2, typename TSpec>
268 inline bool
269 operator !=(Iter<TAlign1, AlignColIterator<TSpec> > & _left,
270             Iter<TAlign2, AlignColIterator<TSpec> > & _right)
271 {
272     return value(_left.data_iterators, 0) != value(_right.data_iterators, 0);
273 }
274 template <typename TAlign1, typename TAlign2, typename TSpec>
275 inline bool
276 operator !=(Iter<TAlign1, AlignColIterator<TSpec> > const & _left,
277             Iter<TAlign2, AlignColIterator<TSpec> > & _right)
278 {
279     return value(_left.data_iterators, 0) != value(_right.data_iterators, 0);
280 }
281 template <typename TAlign1, typename TAlign2, typename TSpec>
282 inline bool
283 operator !=(Iter<TAlign1, AlignColIterator<TSpec> > & _left,
284             Iter<TAlign2, AlignColIterator<TSpec> > const & _right)
285 {
286     return value(_left.data_iterators, 0) != value(_right.data_iterators, 0);
287 }
288 template <typename TAlign1, typename TAlign2, typename TSpec>
289 inline bool
290 operator !=(Iter<TAlign1, AlignColIterator<TSpec> > const & _left,
291             Iter<TAlign2, AlignColIterator<TSpec> > const & _right)
292 {
293     return value(_left.data_iterators, 0) != value(_right.data_iterators, 0);
294 }
295 
296 //////////////////////////////////////////////////////////////////////////////
297 
298 template <typename TAlign, typename TSpec, typename TPosition>
299 inline typename Reference<TAlign>::Type
value(Iter<TAlign,AlignColIterator<TSpec>> & me,TPosition pos_)300 value(Iter<TAlign, AlignColIterator<TSpec> > & me,
301       TPosition pos_)
302 {
303     return value(me.data_iterators[pos_]);
304 }
305 template <typename TAlign, typename TSpec, typename TPosition>
306 inline typename Reference<TAlign>::Type
value(Iter<TAlign,AlignColIterator<TSpec>> const & me,TPosition pos_)307 value(Iter<TAlign, AlignColIterator<TSpec> > const & me,
308       TPosition pos_)
309 {
310     return value(me.data_iterators[pos_]);
311 }
312 //////////////////////////////////////////////////////////////////////////////
313 
314 template <typename TAlign, typename TSpec, typename TPosition>
315 inline typename GetValue<TAlign>::Type
getValue(Iter<TAlign,AlignColIterator<TSpec>> & me,TPosition pos_)316 getValue(Iter<TAlign, AlignColIterator<TSpec> > & me,
317          TPosition pos_)
318 {
319     return getValue(me.data_iterators[pos_]);
320 }
321 template <typename TAlign, typename TSpec, typename TPosition>
322 inline typename GetValue<TAlign>::Type
getValue(Iter<TAlign,AlignColIterator<TSpec>> const & me,TPosition pos_)323 getValue(Iter<TAlign, AlignColIterator<TSpec> > const & me,
324          TPosition pos_)
325 {
326     return getValue(me.data_iterators[pos_]);
327 }
328 
329 //////////////////////////////////////////////////////////////////////////////
330 
331 template <typename TAlign, typename TSpec, typename TPosition, typename TValue>
332 inline void
assignValue(Iter<TAlign,AlignColIterator<TSpec>> & me,TPosition pos_,TValue & val)333 assignValue(Iter<TAlign, AlignColIterator<TSpec> > & me,
334             TPosition pos_,
335             TValue & val)
336 {
337     return assignValue(me.data_iterators[pos_], val);
338 }
339 template <typename TAlign, typename TSpec, typename TPosition, typename TValue>
340 inline void
assignValue(Iter<TAlign,AlignColIterator<TSpec>> & me,TPosition pos_,TValue const & val)341 assignValue(Iter<TAlign, AlignColIterator<TSpec> > & me,
342             TPosition pos_,
343             TValue const & val)
344 {
345     return assignValue(me.data_iterators[pos_], val);
346 }
347 template <typename TAlign, typename TSpec, typename TPosition, typename TValue>
348 inline void
assignValue(Iter<TAlign,AlignColIterator<TSpec>> const & me,TPosition pos_,TValue & val)349 assignValue(Iter<TAlign, AlignColIterator<TSpec> > const & me,
350             TPosition pos_,
351             TValue & val)
352 {
353     return assignValue(me.data_iterators[pos_], val);
354 }
355 template <typename TAlign, typename TSpec, typename TPosition, typename TValue>
356 inline void
assignValue(Iter<TAlign,AlignColIterator<TSpec>> const & me,TPosition pos_,TValue const & val)357 assignValue(Iter<TAlign, AlignColIterator<TSpec> > const & me,
358             TPosition pos_,
359             TValue const & val)
360 {
361     return assignValue(me.data_iterators[pos_], val);
362 }
363 
364 //////////////////////////////////////////////////////////////////////////////
365 
366 template <typename TAlign, typename TSpec, typename TPosition, typename TValue>
367 inline void
moveValue(Iter<TAlign,AlignColIterator<TSpec>> & me,TPosition pos_,TValue & val)368 moveValue(Iter<TAlign, AlignColIterator<TSpec> > & me,
369           TPosition pos_,
370           TValue & val)
371 {
372     return moveValue(me.data_iterators[pos_], val);
373 }
374 template <typename TAlign, typename TSpec, typename TPosition, typename TValue>
375 inline void
moveValue(Iter<TAlign,AlignColIterator<TSpec>> & me,TPosition pos_,TValue const & val)376 moveValue(Iter<TAlign, AlignColIterator<TSpec> > & me,
377           TPosition pos_,
378           TValue const & val)
379 {
380     return moveValue(me.data_iterators[pos_], val);
381 }
382 template <typename TAlign, typename TSpec, typename TPosition, typename TValue>
383 inline void
moveValue(Iter<TAlign,AlignColIterator<TSpec>> const & me,TPosition pos_,TValue & val)384 moveValue(Iter<TAlign, AlignColIterator<TSpec> > const & me,
385           TPosition pos_,
386           TValue & val)
387 {
388     return moveValue(me.data_iterators[pos_], val);
389 }
390 template <typename TAlign, typename TSpec, typename TPosition, typename TValue>
391 inline void
moveValue(Iter<TAlign,AlignColIterator<TSpec>> const & me,TPosition pos_,TValue const & val)392 moveValue(Iter<TAlign, AlignColIterator<TSpec> > const & me,
393           TPosition pos_,
394           TValue const & val)
395 {
396     return moveValue(me.data_iterators[pos_], val);
397 }
398 
399 //////////////////////////////////////////////////////////////////////////////
400 
401 //??? TODO
402 //disabled since GapsIterator has no operator - and +
403 /*
404 template <typename TAlign, typename TSpec, typename TSize>
405 inline Iter<TAlign, AlignColIterator<TSpec> > &
406 operator +=(Iter<TAlign, AlignColIterator<TSpec> > & me,
407             TSize size)
408 {
409     typedef typename Row<TAlign>::Type TRow;
410     typedef typename Iterator<TRow>::Type TRowIterator;
411     typedef String<TRowIterator> TIterators;
412     typedef typename Iterator<TIterators>::Type TIteratorsIterator;
413 
414     TIteratorsIterator _it = begin(me.data_iterators);
415     TIteratorsIterator _it_end = end(me.data_iterators);
416 
417     while (_it != _it_end)
418     {
419         *_it += size;
420         ++_it;
421     }
422     return me;
423 }
424 
425 
426 //////////////////////////////////////////////////////////////////////////////
427 
428 template <typename TAlign, typename TSpec, typename TSize>
429 inline Iter<TAlign, AlignColIterator<TSpec> >
430 operator +(Iter<TAlign, AlignColIterator<TSpec> > & me,
431            TSize size)
432 {
433     Iter<TAlign, AlignColIterator<TSpec> > ret = me;
434     me += size;
435     return me;
436 }
437 template <typename TAlign, typename TSpec, typename TSize>
438 inline Iter<TAlign, AlignColIterator<TSpec> >
439 operator +(Iter<TAlign, AlignColIterator<TSpec> > const & me,
440            TSize size)
441 {
442     Iter<TAlign, AlignColIterator<TSpec> > ret = me;
443     me += size;
444     return me;
445 }
446 
447 //////////////////////////////////////////////////////////////////////////////
448 
449 template <typename TAlign, typename TSpec, typename TSize>
450 inline Iter<TAlign, AlignColIterator<TSpec> > &
451 operator -=(Iter<TAlign, AlignColIterator<TSpec> > & me,
452             TSize size)
453 {
454     typedef typename Row<TAlign>::Type TRow;
455     typedef typename Iterator<TRow>::Type TRowIterator;
456     typedef String<TRowIterator> TIterators;
457     typedef typename Iterator<TIterators>::Type TIteratorsIterator;
458 
459     TIteratorsIterator _it = begin(me.data_iterators);
460     TIteratorsIterator _it_end = end(me.data_iterators);
461 
462     while (_it != _it_end)
463     {
464         *_it -= size;
465         ++_it;
466     }
467     return me;
468 }
469 
470 //////////////////////////////////////////////////////////////////////////////
471 
472 template <typename TAlign, typename TSpec, typename TSize>
473 inline Iter<TAlign, AlignColIterator<TSpec> >
474 operator -(Iter<TAlign, AlignColIterator<TSpec> > & me,
475            TSize size)
476 {
477     Iter<TAlign, AlignColIterator<TSpec> > ret = me;
478     me -= size;
479     return me;
480 }
481 template <typename TAlign, typename TSpec, typename TSize>
482 inline Iter<TAlign, AlignColIterator<TSpec> >
483 operator -(Iter<TAlign, AlignColIterator<TSpec> > const & me,
484            TSize size)
485 {
486     Iter<TAlign, AlignColIterator<TSpec> > ret = me;
487     me -= size;
488     return me;
489 }
490 
491 //____________________________________________________________________________
492 
493 template <typename TAlign, typename TSpec>
494 inline typename Difference<TAlign>::Type
495 operator -(Iter<TAlign, AlignColIterator<TSpec> > const & left,
496            Iter<TAlign, AlignColIterator<TSpec> > const & right)
497 {
498     SEQAN_ASSERT_GT(length(left.data_iterators), 0u);
499     SEQAN_ASSERT_GT(length(right.data_iterators), 0u);
500 
501     return (left.data_iterators[0] - right.data_iterators[0]);
502 }
503 
504 //////////////////////////////////////////////////////////////////////////////
505 
506 template <typename TAlign, typename TSpec>
507 inline typename Position<TAlign>::Type
508 position(Iter<TAlign, AlignColIterator<TSpec> > & me)
509 {
510     return position(me.data_iterators[0], row(host(me), 0));
511 }
512 template <typename TAlign, typename TSpec>
513 inline typename Position<TAlign>::Type
514 position(Iter<TAlign, AlignColIterator<TSpec> > const & me)
515 {
516     return position(me.data_iterators[0], row(host(me), 0));
517 }
518 */
519 //////////////////////////////////////////////////////////////////////////////
520 
521 
522 
523 //////////////////////////////////////////////////////////////////////////////
524 
525 }// namespace seqan
526 
527 #endif //#ifndef SEQAN_HEADER_...
528