Imported Upstream version 0.12.7
[bowtie.git] / SeqAn-1.1 / seqan / sequence / segment_prefix.h
1  /*==========================================================================
2                 SeqAn - The Library for Sequence Analysis
3                           http://www.seqan.de 
4  ============================================================================
5   Copyright (C) 2007
6
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.
11
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.
16
17  ============================================================================
18   $Id: segment_prefix.h,v 1.1 2008/08/25 16:20:04 langmead Exp $
19  ==========================================================================*/
20
21 #ifndef SEQAN_HEADER_SEGMENT_PREFIX_H
22 #define SEQAN_HEADER_SEGMENT_PREFIX_H
23
24
25 namespace SEQAN_NAMESPACE_MAIN
26 {
27
28 //////////////////////////////////////////////////////////////////////////////
29 // PrefixSegment
30 //////////////////////////////////////////////////////////////////////////////
31
32
33 /**
34 .Spec.PrefixSegment:
35 ..cat:Segments
36 ..summary:First part of a sequence.
37 ..general:Class.Segment
38 ..signature:Segment<THost, PrefixSegment>
39 ..param.THost:Type of the whole sequence.
40 ...text:Instances of $Segment<THost, PrefixSegment>$ are prefixes 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.Prefix@ instead of explicitely 
44         choose a specialization of @Class.Segment@.
45 ..see:Spec.InfixSegment
46 ..see:Spec.SuffixSegment
47 ..see:Metafunction.Prefix
48 */
49
50 struct PrefixSegment;
51
52 template <typename THost_>
53 class Segment<THost_, PrefixSegment>
54 {
55 protected:
56         typedef typename Host<Segment>::Type THost;
57
58         typename _Pointer<THost>::Type data_host;
59         typename Position<THost>::Type data_end_position;
60
61 //____________________________________________________________________________
62
63 public:
64
65 /**
66 .Memfunc.PrefixSegment#Segment:
67 ..class:Spec.PrefixSegment
68 ..summary:Constructor
69 ..signature:Segment<THost, PrefixSegment> ()
70 ..signature:Segment<THost, PrefixSegment> (prefix)
71 ..signature:Segment<THost, PrefixSegment> (host [, end])
72 ..param.prefix:Other prefix object. (copy constructor)
73 ..param.host:The whole sequence.
74 ..param.end:Position in $host$ behind the last item in segment. (optional)
75 ...default:$length(host)$
76 ...type:Metafunction.Position.$Position<THost>::Type$
77 ...type:Metafunction.Iterator.$Iterator<THost>::Type$
78 ..remarks:
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 
85 of the host object.
86 ...text:$begin$ must be a valid position/iterator in $host$.
87 If $begin$ is omitted, the prefix segment corresponding to
88 the whole sequence $host$ is constructed.
89 This is the same segment that is returned by @Function.goBegin@.
90 */
91         Segment():
92                 data_end_position(0)
93         {
94 SEQAN_CHECKPOINT
95         }
96
97         Segment(THost & _host):
98                 data_host(& _host),
99                 data_end_position(length(_host))
100         {
101 SEQAN_CHECKPOINT
102         }
103
104         Segment(typename _Parameter<THost>::Type _host, typename Position<THost>::Type _end_index):
105                 data_host(_toPointer(_host)),
106                 data_end_position(_end_index)
107         {
108 SEQAN_CHECKPOINT
109         }
110 /*
111         Segment(typename _Parameter<THost>::Type _host, typename Iterator<THost, Rooted>::Type _end):
112                 data_host(_toPointer(_host)),
113                 data_end_position(position(_end))
114         {
115 SEQAN_CHECKPOINT
116         }
117 */
118         Segment(typename _Parameter<THost>::Type _host, typename Iterator<THost, Standard>::Type _end):
119                 data_host(_toPointer(_host)),
120                 data_end_position(position(_end, _host))
121         {
122 SEQAN_CHECKPOINT
123         }
124
125 /*
126         Segment(Segment const & _other):
127                 data_host(_other.data_host),
128                 data_end_position(_other.data_end_position)
129         {
130 SEQAN_CHECKPOINT
131         }
132 */
133         template <typename THost2, typename TSpec2>
134         Segment(Segment<THost2, TSpec2> const & _other):
135                 data_host(_toPointer(host(_other))),
136                 data_end_position(endPosition(_other))
137         {
138 SEQAN_CHECKPOINT
139         }
140
141         ~ Segment() 
142         {
143 SEQAN_CHECKPOINT
144         }
145
146         template <typename TSource>
147         inline Segment & 
148         operator = (TSource const & source)
149         {
150                 assign(*this, source);
151                 return *this;
152         }
153         inline Segment & 
154         operator = (Segment const & source)
155         {
156                 assign(*this, source);
157                 return *this;
158         }
159 //____________________________________________________________________________
160
161 public:
162
163         friend inline typename _Parameter<THost>::Type 
164         host(Segment & me)
165         {
166 SEQAN_CHECKPOINT
167                 return _toParameter<THost>(me.data_host);
168         }
169
170         friend inline typename _Parameter<THost>::Type 
171         host(Segment const & me)
172         {
173 SEQAN_CHECKPOINT
174                 return _toParameter<THost>(me.data_host);
175         }
176
177 //____________________________________________________________________________
178
179         friend inline void 
180         setHost(Segment & me, typename _Parameter<THost>::Type _host)
181         {
182 SEQAN_CHECKPOINT
183                 me.data_host = _toPointer(_host);
184         }
185
186 //____________________________________________________________________________
187
188         template <typename TPos>
189         inline typename Reference<Segment>::Type
190         operator [] (TPos pos)
191         {
192 SEQAN_CHECKPOINT
193                 return value(*this, pos);
194         }
195
196         template <typename TPos>
197         inline typename Reference<Segment const>::Type 
198         operator [] (TPos pos) const
199         {
200 SEQAN_CHECKPOINT
201                 return value(*this, pos);
202         }
203
204 //____________________________________________________________________________
205
206         friend inline typename Iterator<Segment, Standard>::Type 
207         begin(Segment & me,
208                 Standard)
209         {
210 SEQAN_CHECKPOINT
211                 return begin(host(me), Standard());
212         }
213         friend inline typename Iterator<Segment const, Standard>::Type 
214         begin(Segment const & me,
215                 Standard)
216         {
217 SEQAN_CHECKPOINT
218                 return begin(host(me), Standard());
219         }
220
221 //____________________________________________________________________________
222
223         friend inline typename Position<Segment const>::Type 
224         beginPosition(Segment const & /*me*/)
225         {
226 SEQAN_CHECKPOINT
227                 return 0;
228         }
229         friend inline typename Position<Segment>::Type 
230         beginPosition(Segment & /*me*/)
231         {
232 SEQAN_CHECKPOINT
233                 return 0;
234         }
235
236 //____________________________________________________________________________
237
238         template <typename TIterator>
239         friend inline void
240         setBegin(Segment &, TIterator)
241         {
242         }
243
244 //____________________________________________________________________________
245
246         friend inline typename Iterator<Segment, Standard>::Type 
247         end(Segment & me,
248                 Standard)
249         {
250 SEQAN_CHECKPOINT
251                 return begin(host(me), Standard()) + me.data_end_position;
252         }
253         friend inline typename Iterator<Segment const, Standard>::Type 
254         end(Segment const & me,
255                 Standard)
256         {
257 SEQAN_CHECKPOINT
258                 return begin(host(me), Standard()) + me.data_end_position;
259         }
260
261 //____________________________________________________________________________
262
263 /* //unnoetig
264         friend inline void 
265         setEnd(Segment & me)
266         {
267 SEQAN_CHECKPOINT
268                 me.data_end_position = length(host(me));
269         }
270 */
271         friend inline void 
272         setEndPosition(Segment & me, typename Position<Segment>::Type new_end)
273         {
274 SEQAN_CHECKPOINT
275                 me.data_end_position = new_end;
276         }
277
278         friend inline void 
279         setEnd(Segment & me, typename Iterator<Segment, Standard>::Type new_end)
280         {
281 SEQAN_CHECKPOINT
282                 me.data_end_position = new_end - begin(host(me));//, Standard());
283         }
284
285         friend inline void 
286         setEnd(typename Iterator<Segment, Rooted>::Type new_end)
287         {
288 SEQAN_CHECKPOINT
289                 container(new_end).data_end_position = hostIterator(new_end) - begin(host(container(new_end)));//, Standard());
290         }
291
292 //____________________________________________________________________________
293
294         friend inline void 
295         _setLength(
296                 Segment & me, 
297                 typename Size<THost>::Type new_length)
298         {
299 SEQAN_CHECKPOINT
300                 me.data_end_position = new_length;
301         }
302
303 //____________________________________________________________________________
304
305         friend inline typename Position<Segment>::Type 
306         endPosition(Segment & me)
307         {
308 SEQAN_CHECKPOINT
309                 return me.data_end_position;
310         }
311         friend inline typename Position<Segment const>::Type 
312         endPosition(Segment const & me)
313         {
314 SEQAN_CHECKPOINT
315                 return me.data_end_position;
316         }
317
318 //____________________________________________________________________________
319 };
320
321 //////////////////////////////////////////////////////////////////////////////
322
323 /**
324 .Metafunction.Prefix:
325 ..summary:Prefix sequence type.
326 ..signature:Prefix<T>::Type
327 ..param.T:A sequence type.
328 ...type:Class.String
329 ..returns.param.Type:The prefix type.
330 ..see:Spec.PrefixSegment
331 ..see:Metafunction.Infix
332 */
333
334 struct InfixSegment;
335 struct SuffixSegment;
336
337 template <typename THost>
338 struct Prefix
339 {
340         typedef Segment<THost, PrefixSegment> Type;
341 };
342
343 template <typename THost>
344 struct Prefix< Segment<THost, InfixSegment> >
345 {
346         typedef Segment<THost, InfixSegment> Type;
347 };
348 template <typename THost>
349 struct Prefix< Segment<THost, SuffixSegment> >
350 {
351         typedef Segment<THost, InfixSegment> Type;
352 };
353 template <typename THost>
354 struct Prefix< Segment<THost, PrefixSegment> >
355 {
356         typedef Segment<THost, PrefixSegment> Type;
357 };
358
359 template <typename THost, typename TSpec>
360 struct Prefix< Segment<THost, TSpec> const >:
361         Prefix< Segment<THost, TSpec> > {};
362
363
364 //////////////////////////////////////////////////////////////////////////////
365
366 template <typename THost, typename TPosition>
367 inline void
368 set(Segment<THost, PrefixSegment> & me,
369         THost & host_,
370         TPosition end_)
371 {
372 SEQAN_CHECKPOINT
373         setHost(me, host_);
374         setEnd(me, end_);
375 }
376 //____________________________________________________________________________
377
378 template <typename THost>
379 inline void
380 set(Segment<THost, PrefixSegment> & me,
381         THost & host_)
382 {
383 SEQAN_CHECKPOINT
384         setHost(me, host_);
385         setEnd(me, end(host_));
386 }
387
388 //____________________________________________________________________________
389
390 template <typename THost, typename TSpec>
391 inline void
392 set(Segment<THost, PrefixSegment> & me,
393         Segment<THost, TSpec> & source)
394 {
395 SEQAN_CHECKPOINT
396         setHost(me, host(source));
397         setEndPosition(me, endPosition(source));
398 }
399
400 template <typename THost, typename TSpec>
401 inline void
402 set(Segment<THost, PrefixSegment> & me,
403         Segment<THost, TSpec> const & source)
404 {
405 SEQAN_CHECKPOINT
406         setHost(me, host(source));
407         setEndPosition(me, endPosition(source));
408 }
409
410 //////////////////////////////////////////////////////////////////////////////
411
412 template <typename THost>
413 inline bool
414 atBegin(Segment<THost, PrefixSegment> const & segment)
415 {
416 SEQAN_CHECKPOINT
417         return (endPosition(segment) == length(host(segment)));
418 }
419
420 //////////////////////////////////////////////////////////////////////////////
421
422 template <typename THost>
423 inline bool
424 atEnd(Segment<THost, PrefixSegment> const & segment)
425 {
426 SEQAN_CHECKPOINT
427         return (endPosition(segment) == 0);
428 }
429
430 //////////////////////////////////////////////////////////////////////////////
431
432 template <typename THost>
433 inline void
434 goBegin(Segment<THost, PrefixSegment> & segment,
435                 THost &)
436 {
437 SEQAN_CHECKPOINT
438         goBegin(segment);
439 }
440
441 template <typename THost>
442 inline void
443 goBegin(Segment<THost, PrefixSegment> & segment)
444 {
445         setEnd(segment);
446 }
447
448 //////////////////////////////////////////////////////////////////////////////
449
450 template <typename THost>
451 inline void
452 goEnd(Segment<THost, PrefixSegment> & segment,
453           THost &)
454 {
455 SEQAN_CHECKPOINT
456         goEnd(segment);
457 }
458
459 template <typename THost>
460 inline void
461 goEnd(Segment<THost, PrefixSegment> & segment)
462 {
463         setEnd(segment, 0);
464 }
465
466 //////////////////////////////////////////////////////////////////////////////
467
468 template <typename THost>
469 inline Segment<THost, PrefixSegment> &
470 operator ++(Segment<THost, PrefixSegment> & segment)
471 {
472         setEnd(segment, endPosition(segment) - 1);
473         return segment;
474 }
475
476 //////////////////////////////////////////////////////////////////////////////
477
478 template <typename THost>
479 inline Segment<THost, PrefixSegment> &
480 operator --(Segment<THost, PrefixSegment> & segment)
481 {
482         setEnd(segment, endPosition(segment) + 1);
483         return segment;
484 }
485
486 //////////////////////////////////////////////////////////////////////////////
487
488 /**
489 .Function.prefix:
490 ..cat:Containers
491 ..summary:Creates prefix object.
492 ..signature:prefix(host, end)
493 ..param.host:The complete sequence.
494 ...type:Class.String
495 ...type:Adaption.char array
496 ..param.end:Position or iterator behind the last element of the segment.
497 ...type:Metafunction.Position
498 ...type:Metafunction.Iterator
499 ..returns:The prefix of $host that begins at $begin$.
500 ...remarks:The type of the prefix is given by @Metafunction.Prefix@.
501 ..remarks:Notational sugar.
502 ..see:Spec.PrefixSegment
503 ..see:Function.suffix
504 ..see:Function.infix
505 */
506
507 template <typename T, typename TPosEnd>
508 inline typename Prefix<T>::Type
509 prefix(T & t, TPosEnd pos_end)
510 {
511 SEQAN_CHECKPOINT
512         return typename Prefix<T>::Type(t, pos_end);
513 }
514
515 template <typename T, typename TPosEnd>
516 inline typename Prefix<T *>::Type
517 prefix(T * t, TPosEnd pos_end)
518 {
519 SEQAN_CHECKPOINT
520         return typename Prefix<T *>::Type (t, pos_end);
521 }
522
523 //////////////////////////////////////////////////////////////////////////////
524 // A prefix of a prefix -> is a prefix
525 template <typename T, typename TPosEnd>
526 inline typename Prefix<Segment<T, PrefixSegment> >::Type
527 prefix(Segment<T, PrefixSegment> & t, TPosEnd pos_end)
528 {
529 SEQAN_CHECKPOINT
530         return typename Prefix<Segment<T, PrefixSegment> >::Type (
531                 host(t), 
532                 beginPosition(t) + pos_end);
533 }
534 template <typename T, typename TPosEnd>
535 inline typename Prefix<Segment<T, PrefixSegment> const>::Type
536 prefix(Segment<T, PrefixSegment> const & t, TPosEnd pos_end)
537 {
538 SEQAN_CHECKPOINT
539         return typename Prefix<Segment<T, PrefixSegment> const>::Type (
540                 host(t), 
541                 beginPosition(t) + pos_end);
542 }
543
544 //////////////////////////////////////////////////////////////////////////////
545 // A prefix of an infix -> is an infix
546 template <typename T, typename TPosEnd>
547 inline typename Prefix<Segment<T, InfixSegment> >::Type
548 prefix(Segment<T, InfixSegment> & t, TPosEnd pos_end)
549 {
550 SEQAN_CHECKPOINT
551         return typename Prefix<Segment<T, InfixSegment> >::Type (
552                 host(t), 
553                 beginPosition(t),
554                 beginPosition(t) + pos_end);
555 }
556 template <typename T, typename TPosEnd>
557 inline typename Prefix<Segment<T, InfixSegment> const>::Type
558 prefix(Segment<T, InfixSegment> const & t, TPosEnd pos_end)
559 {
560 SEQAN_CHECKPOINT
561         return typename Prefix<Segment<T, InfixSegment> const>::Type (
562                 host(t), 
563                 beginPosition(t),
564                 beginPosition(t) + pos_end);
565 }
566
567
568 //////////////////////////////////////////////////////////////////////////////
569 // A prefix of an suffix -> is an infix
570 template <typename T, typename TPosEnd>
571 inline typename Prefix<Segment<T, SuffixSegment> >::Type
572 prefix(Segment<T, SuffixSegment> & t, TPosEnd pos_end)
573 {
574 SEQAN_CHECKPOINT
575         return typename Prefix<Segment<T, SuffixSegment> >::Type (
576                 host(t), 
577                 beginPosition(t),
578                 beginPosition(t) + pos_end);
579 }
580 template <typename T, typename TPosEnd>
581 inline typename Prefix<Segment<T, SuffixSegment> const>::Type
582 prefix(Segment<T, SuffixSegment> const & t, TPosEnd pos_end)
583 {
584 SEQAN_CHECKPOINT
585         return typename Prefix<Segment<T, SuffixSegment> const>::Type (
586                 host(t), 
587                 beginPosition(t),
588                 beginPosition(t) + pos_end);
589 }
590
591 //////////////////////////////////////////////////////////////////////////////
592
593 } //namespace SEQAN_NAMESPACE_MAIN
594
595 #endif //#ifndef SEQAN_HEADER_...