1 /*==========================================================================
2 SeqAn - The Library for Sequence Analysis
4 ============================================================================
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 ============================================================================
18 $Id: segment_infix.h,v 1.1 2008/08/25 16:20:04 langmead Exp $
19 ==========================================================================*/
21 #ifndef SEQAN_HEADER_SEGMENT_INFIX_H
22 #define SEQAN_HEADER_SEGMENT_INFIX_H
25 namespace SEQAN_NAMESPACE_MAIN
28 //////////////////////////////////////////////////////////////////////////////
30 //////////////////////////////////////////////////////////////////////////////
36 ..summary:An arbitrary segment.
37 ..general:Class.Segment
38 ..signature:Segment<THost, InfixSegment>
39 ..param.THost:Type of the whole sequence.
40 ...text:Instances of $Segment<THost, InfixSegment>$ are infixes of $THost$ objects.
41 ...remarks:Use @Metafunction.Host@ to get the host type for a given class.
42 ..remarks.note:Since the appropriate segment type depends on the host sequence type,
43 it is recommended to use the metafunction @Metafunction.Infix@ instead of explicitely
44 choose a specialization of @Class.Segment@.
45 ..see:Metafunction.Infix
48 template <typename THost_>
49 class Segment<THost_, InfixSegment>
52 typedef typename Host<Segment>::Type THost;
54 typename _Pointer<THost>::Type data_host;
55 typename Position<THost>::Type data_begin_position;
56 typename Position<THost>::Type data_end_position;
59 //____________________________________________________________________________
64 .Memfunc.InfixSegment#Segment:
65 ..class:Spec.InfixSegment
67 ..signature:Segment<THost, InfixSegment> ()
68 ..signature:Segment<THost, InfixSegment> (infix)
69 ..signature:Segment<THost, InfixSegment> (host [, begin, end])
70 ..param.infix:Other infix object. (copy constructor)
71 ..param.host:The whole sequence.
72 ..param.begin:Position/iterator in $host$ of the first item in segment.
73 ...type:Metafunction.Position.$Position<THost>::Type$
74 ...type:Metafunction.Iterator.$Iterator<THost>::Type$
75 ..param.end:Position/iterator behind the end of the segment.
76 ...type:Metafunction.Position.$Position<THost>::Type$
77 ...type:Metafunction.Iterator.$Iterator<THost>::Type$
79 ...text:A Segment object cannot work without a host. If the object is default constructed,
80 the host must be set by @Function.setHost@ before the segment can be used.
81 ...text:If a segment object is constructed by the copy constructor, the
82 members of the new constructed object are set to the same values as the members in the
83 source object; the host object is not modified.
84 Note that this is a special case, since all other copy operations result in changes
86 ...text:$begin$ and $end$ must be valid positions/iterators in $host$.
87 If $begin$ und $end$ are omitted, the infix segment corresponding to
88 the first character of $host$ is constructed.
89 This is the same segment that is returned by @Function.goBegin@.
92 data_begin_position(0),
98 Segment(typename _Parameter<THost>::Type _host):
99 data_host(_toPointer(_host)),
100 data_begin_position(0),
106 Segment(typename _Parameter<THost>::Type _host, typename Position<THost>::Type _begin_index, typename Position<THost>::Type _end_index):
107 data_host(_toPointer(_host)),
108 data_begin_position(_begin_index),
109 data_end_position(_end_index)
114 Segment(typename _Parameter<THost>::Type _host, typename Iterator<THost, Rooted>::Type _begin, typename Iterator<THost, Rooted>::Type _end):
115 data_host(_toPointer(_host)),
116 data_begin_position(position(_begin)),
117 data_end_position(position(_end))
122 Segment(typename _Parameter<THost>::Type _host, typename Iterator<THost, Standard>::Type _begin, typename Iterator<THost, Standard>::Type _end):
123 data_host(_toPointer(_host)),
124 data_begin_position(position(_begin, _host)),
125 data_end_position(position(_end, _host))
129 template <typename THost2, typename TSpec2>
130 Segment(Segment<THost2, TSpec2> const & _other):
131 data_host(_toPointer(host(_other))),
132 data_begin_position(beginPosition(_other)),
133 data_end_position(endPosition(_other))
143 template <typename TSource>
145 operator = (TSource const & source)
147 assign(*this, source);
151 operator = (Segment const & source)
153 assign(*this, source);
156 //____________________________________________________________________________
160 ///Function.host.param.object.type:Class.Segment
162 friend inline typename _Parameter<THost>::Type
166 return _toParameter<THost>(me.data_host);
169 friend inline typename _Parameter<THost>::Type
170 host(Segment const & me)
173 return _toParameter<THost>(me.data_host);
176 //____________________________________________________________________________
180 ..summary:Sets the host of an object.
181 ..cat:Dependent Objects
182 ..signature:setHost(object, host)
183 ..param.object:The object that will get a new host.
184 ...type:Class.Segment
185 ..param.host:The new host.
186 ..remarks:After this operation, $object$ depends on $host$.
187 ...text:Note that setting the host can invalidate $object$.
188 For example, if one changes the host of a @Class.Segment@ object, it is possible
189 that begin- and end-position of the segment does not fit into the new host sequence.
193 setHost(Segment & me, typename _Parameter<THost>::Type _host)
196 me.data_host = _toPointer(_host);
199 //____________________________________________________________________________
201 template <typename TPos>
202 inline typename Reference<Segment>::Type
203 operator [] (TPos pos)
206 return value(*this, pos);
209 template <typename TPos>
210 inline typename Reference<Segment const>::Type
211 operator [] (TPos pos) const
214 return value(*this, pos);
217 //____________________________________________________________________________
219 ///.Function.begin.param.object.type:Class.Segment
221 friend inline typename Iterator<Segment, Standard>::Type
226 return begin(host(me), Standard()) + me.data_begin_position;
228 friend inline typename Iterator<Segment const, Standard>::Type
229 begin(Segment const & me,
233 return begin(host(me), Standard()) + me.data_begin_position;
236 //____________________________________________________________________________
238 ///.Function.beginPosition.param.object.type:Class.Segment
240 friend inline typename Position<Segment>::Type
241 beginPosition(Segment & me)
244 return me.data_begin_position;
246 friend inline typename Position<Segment const>::Type
247 beginPosition(Segment const & me)
250 return me.data_begin_position;
253 //____________________________________________________________________________
257 ..summary:Sets begin of object in host.
258 ..cat:Dependent Objects
259 ..signature:setBegin(object, new_begin)
260 ..param.object:An object.
261 ...type:Spec.InfixSegment
262 ...type:Spec.SuffixSegment
263 ..param.new_begin:iterator to the new first item in $host(object)$ that belongs of $object$.
264 ...type:Metafunction.Iterator
266 ..see:Function.beginPosition
268 template <typename TIterator>
270 setBegin(Segment & me, TIterator new_begin)
273 me.data_begin_position = new_begin - begin(host(me));//, Standard());
277 //____________________________________________________________________________
280 .Function.setBeginPosition:
281 ..summary:Sets begin position of object in host.
282 ..cat:Dependent Objects
283 ..signature:setBeginPosition(object, new_begin)
284 ..param.object:An object.
285 ...type:Spec.InfixSegment
286 ...type:Spec.SuffixSegment
287 ..param.new_begin:position of the new first item in $host(object)$ that belongs of $object$.
288 ...type:Metafunction.Position
290 ..see:Function.beginPosition
291 ..see:Function.setBegin
294 template <typename TPosition>
296 setBeginPosition(Segment & me, TPosition new_begin)
299 me.data_begin_position = new_begin;
302 //____________________________________________________________________________
304 ///.Function.begin.param.object.type:Class.Segment
306 friend inline typename Iterator<Segment, Standard>::Type
311 return begin(host(me), Standard()) + me.data_end_position;
313 friend inline typename Iterator<Segment const, Standard>::Type
314 end(Segment const & me,
318 return begin(host(me), Standard()) + me.data_end_position;
321 //____________________________________________________________________________
323 ///.Function.endPosition.param.object.type:Class.Segment
325 friend inline typename Position<Segment>::Type
326 endPosition(Segment & me)
329 return me.data_end_position;
331 friend inline typename Position<Segment>::Type
332 endPosition(Segment const & me)
335 return me.data_end_position;
338 //____________________________________________________________________________
342 ..summary:Sets end of object in host.
343 ..cat:Dependent Objects
344 ..signature:setEnd(object, new_end)
345 ..param.object:An object.
346 ...type:Spec.InfixSegment
347 ...type:Spec.PrefixSegment
348 ..param.new_end:Iterator behind the last item in $host(object)$ belongs of $object$.
349 ...type:Metafunction.Iterator
351 ..see:Function.endPosition
352 ..see:Function.setBegin
355 template <typename TIterator>
357 setEnd(Segment & me, TIterator new_end)
360 me.data_end_position = new_end - begin(host(me));//, Standard());
368 setEnd(me, end(host(me)));
371 //____________________________________________________________________________
375 .Function.setEndPosition:
376 ..summary:Sets begin position of object in host.
377 ..cat:Dependent Objects
378 ..signature:setEndPosition(object, new_end)
379 ..param.object:An object.
380 ...type:Spec.InfixSegment
381 ...type:Spec.PrefixSegment
382 ..param.new_end:position behind the last item in $host(object)$ that belongs of $object$.
383 ...type:Metafunction.Position
385 ..see:Function.endPosition
386 ..see:Function.setBeginPosition
387 ..see:Function.setEnd
390 template <typename TPosition>
392 setEndPosition(Segment & me, TPosition new_end)
395 me.data_end_position = new_end;
398 //____________________________________________________________________________
403 typename Size<THost>::Type new_length)
406 me.data_end_position = me.data_begin_position + new_length;
409 //____________________________________________________________________________
413 //////////////////////////////////////////////////////////////////////////////
417 ..summary:Infix sequence type.
418 ..signature:Infix<T>::Type
419 ..param.T:A sequence type.
421 ..returns.param.Type:The infix type.
422 ..see:Spec.InfixSegment
425 template <typename THost>
428 typedef Segment<THost, InfixSegment> Type;
431 template <typename THost, typename TSpec>
432 struct Infix< Segment<THost, TSpec> >
434 typedef Segment<THost, InfixSegment> Type;
437 template <typename THost, typename TSpec>
438 struct Infix< Segment<THost, TSpec> const >:
439 Infix< Segment<THost, TSpec> > {};
441 //////////////////////////////////////////////////////////////////////////////
443 template <typename THost, typename TPosition1, typename TPosition2>
445 set(Segment<THost, InfixSegment> & me,
452 setBegin(me, begin_);
455 //____________________________________________________________________________
457 template <typename THost>
459 set(Segment<THost, InfixSegment> & me,
464 setBegin(me, begin(host_, Standard()));
465 setEnd(me, end(host_, Standard()));
467 template <typename THost>
469 set(Segment<THost, InfixSegment> & me,
474 setBegin(me, begin(host_, Standard()));
475 setEnd(me, end(host_, Standard()));
478 //____________________________________________________________________________
480 template <typename THost, typename TSpec>
482 set(Segment<THost, InfixSegment> & me,
483 Segment<THost, TSpec> & source)
486 setHost(me, host(source));
487 setBeginPosition(me, beginPosition(source));
488 setEndPosition(me, endPosition(source));
490 template <typename THost, typename TSpec>
492 set(Segment<THost, InfixSegment> & me,
493 Segment<THost, TSpec> const & source)
496 setHost(me, host(source));
497 setBeginPosition(me, beginPosition(source));
498 setEndPosition(me, endPosition(source));
501 //////////////////////////////////////////////////////////////////////////////
503 template <typename THost>
505 atBegin(Segment<THost, InfixSegment> & segment)
508 return (beginPosition(segment) == endPosition(segment));
510 template <typename THost>
512 atBegin(Segment<THost, InfixSegment> const & segment)
515 return (beginPosition(segment) == endPosition(segment));
518 //////////////////////////////////////////////////////////////////////////////
520 template <typename THost>
522 atEnd(Segment<THost, InfixSegment> & segment)
525 return (endPosition(segment) - beginPosition(segment)) > length(host(segment));
527 template <typename THost>
529 atEnd(Segment<THost, InfixSegment> const & segment)
532 return (endPosition(segment) - beginPosition(segment)) > length(host(segment));
536 //////////////////////////////////////////////////////////////////////////////
538 template <typename THost>
540 goBegin(Segment<THost, InfixSegment> & segment)
543 setBeginPosition(segment, 0);
544 setEndPosition(segment, 1);
546 template <typename THost, typename THost2>
548 goBegin(Segment<THost, InfixSegment> & segment,
553 template <typename THost, typename THost2>
555 goBegin(Segment<THost, InfixSegment> & segment,
561 //////////////////////////////////////////////////////////////////////////////
564 template <typename THost>
566 goEnd(Segment<THost, InfixSegment> & segment)
569 setBeginPosition(segment, 0);
570 setEndPosition(segment, length(host(segment)));
572 template <typename THost, typename THost2>
574 goEnd(Segment<THost, InfixSegment> & segment,
579 template <typename THost, typename THost2>
581 goEnd(Segment<THost, InfixSegment> & segment,
587 //////////////////////////////////////////////////////////////////////////////
589 template <typename THost>
590 inline Segment<THost, InfixSegment> &
591 operator ++(Segment<THost, InfixSegment> & segment)
594 if (endPosition(segment) == length(host(segment)))
596 setEndPosition(segment, endPosition(segment) - beginPosition(segment) + 1);
597 setBeginPosition(segment, 0);
601 setBeginPosition(segment, beginPosition(segment) + 1);
602 setEndPosition(segment, endPosition(segment) + 1);
607 //////////////////////////////////////////////////////////////////////////////
609 template <typename THost>
610 inline Segment<THost, InfixSegment> &
611 operator --(Segment<THost, InfixSegment> & segment)
614 if (!beginPosition(segment))
616 typename Size<THost>::Type host_length = length(host(segment));
618 setBeginPosition(segment, host_length - endPosition(segment) + beginPosition(segment) + 1);
619 setEndPosition(segment, host_length);
623 setBeginPosition(segment, beginPosition(segment) - 1);
624 setEndPosition(segment, endPosition(segment) - 1);
629 //////////////////////////////////////////////////////////////////////////////
631 template <typename THost, typename TSpec, typename TPos>
632 inline typename Reference< Segment<THost, TSpec> >::Type
633 value(Segment<THost, TSpec> & me,
637 return *(begin(me, Standard()) + pos);
640 template <typename THost, typename TSpec, typename TPos>
641 inline typename Reference< Segment<THost, TSpec> const >::Type
642 value(Segment<THost, TSpec> const & me,
646 return *(begin(me, Standard()) + pos);
649 //////////////////////////////////////////////////////////////////////////////
654 ..summary:Creates infix object.
655 ..signature:infix(host, begin, end)
656 ..param.host:The complete sequence.
658 ...type:Adaption.char array
659 ..param.begin:Position or iterator of the first element of the segment.
660 ...type:Metafunction.Position
661 ...type:Metafunction.Iterator
662 ..param.end:Position or iterator behind the last element of the segment.
663 ...remarks:$end$ must have the same type as $begin$.
664 ..returns:The infix of $host$ between $begin$ and $end-1$.
665 ...remarks:The type of the infix is given by @Metafunction.Infix@.
666 ..remarks:Notational sugar.
667 ..see:Spec.InfixSegment
670 template <typename T, typename TPosBegin, typename TPosEnd>
671 inline typename Infix<T>::Type
672 infix(T & t, TPosBegin pos_begin, TPosEnd pos_end)
675 return typename Infix<T>::Type(t, pos_begin, pos_end);
678 template <typename T, typename TPosBegin, typename TPosEnd>
679 inline typename Infix<T *>::Type
680 infix(T * t, TPosBegin pos_begin, TPosEnd pos_end)
683 return typename Infix<T *>::Type (t, pos_begin, pos_end);
686 template <typename T, typename TSpec, typename TPosBegin, typename TPosEnd>
687 inline typename Infix<Segment<T, TSpec> >::Type
688 infix(Segment<T, TSpec> & t, TPosBegin pos_begin, TPosEnd pos_end)
691 return typename Infix<Segment<T, TSpec> >::Type (
693 beginPosition(t) + pos_begin,
694 beginPosition(t) + pos_end);
697 template <typename T, typename TSpec, typename TPosBegin, typename TPosEnd>
698 inline typename Infix<Segment<T, TSpec> const>::Type
699 infix(Segment<T, TSpec> const & t, TPosBegin pos_begin, TPosEnd pos_end)
702 return typename Infix<Segment<T, TSpec> const>::Type (
704 beginPosition(t) + pos_begin,
705 beginPosition(t) + pos_end);
708 //////////////////////////////////////////////////////////////////////////////
711 .Function.infixWithLength:
713 ..summary:Creates infix object.
714 ..signature:infixWithLength(host, begin, length)
715 ..param.host:The complete sequence.
717 ...type:Adaption.char array
718 ..param.begin:Position or iterator of the first element of the segment.
719 ...type:Metafunction.Position
720 ...type:Metafunction.Iterator
721 ..param.length:Length of the returned infix.
722 ..returns:The infix of $host$ between $begin$ and $begin+length-1$.
723 ...remarks:The type of the infix is given by @Metafunction.Infix@.
724 ..remarks:Notational sugar.
725 ..see:Spec.InfixSegment
728 template <typename T, typename TPosBegin, typename TSize>
729 inline typename Infix<T>::Type
730 infixWithLength(T & t, TPosBegin pos_begin, TSize length)
733 return typename Infix<T>::Type(t, pos_begin, pos_begin + length);
736 template <typename T, typename TPosBegin, typename TSize>
737 inline typename Infix<T *>::Type
738 infixWithLength(T * t, TPosBegin pos_begin, TSize length)
741 return typename Infix<T *>::Type (t, pos_begin, pos_begin + length);
744 template <typename T, typename TSpec, typename TPosBegin, typename TSize>
745 inline typename Infix<Segment<T, TSpec> >::Type
746 infixWithLength(Segment<T, TSpec> & t, TPosBegin pos_begin, TSize length)
749 return typename Infix<Segment<T, TSpec> >::Type (
751 beginPosition(t) + pos_begin,
752 beginPosition(t) + pos_begin + length);
755 template <typename T, typename TSpec, typename TPosBegin, typename TSize>
756 inline typename Infix<Segment<T, TSpec> const>::Type
757 infixWithLength(Segment<T, TSpec> const & t, TPosBegin pos_begin, TSize length)
760 return typename Infix<Segment<T, TSpec> const>::Type (
762 beginPosition(t) + pos_begin,
763 beginPosition(t) + pos_begin + length);
766 //////////////////////////////////////////////////////////////////////////////
770 template <typename TIterator>
772 setBegin(TIterator new_begin)
775 setBegin(container(new_begin), hostIterator(new_begin));
779 //////////////////////////////////////////////////////////////////////////////
782 template <typename TIterator>
784 setEnd(TIterator new_end)
787 setEnd(container(new_end), new_end);
790 //////////////////////////////////////////////////////////////////////////////
792 } //namespace SEQAN_NAMESPACE_MAIN
794 #endif //#ifndef SEQAN_HEADER_...