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 // Author: David Weese <david.weese@fu-berlin.de>
34 // ==========================================================================
35 // Declarations related to and implementation of the Segment class.
36 // ==========================================================================
37 
38 #ifndef SEQAN_HEADER_SEGMENT_BASE_H
39 #define SEQAN_HEADER_SEGMENT_BASE_H
40 
41 
42 namespace seqan
43 {
44 
45 /*!
46  * @concept SegmentableConcept
47  * @extends ContainerConcept
48  * @headerfile <seqan/sequence.h>
49  * @brief A concept for containers that can be used as the host of a @link Segment segment @endlink.
50  *
51  * @signature concept Segmentable;
52  * @brief Returns prefix type in a infix fashion.
53  */
54 
55 /*!
56  * @mfn SegmentableConcept#Prefix
57  * @brief Return prefix type in a flattening fashion.
58  *
59  * @signature Prefix<TSeq>::Type
60  *
61  * @tparam TSeq The segmentable sequence type to get prefix type for.
62  * @return Type The prefix type.
63  *
64  * The prefix type of a prefix is a suffix, the prefix of any other segment type is an infix.
65  */
66 
67 /*!
68  * @fn SegmentableConcept#prefix
69  * @brief Returns the prefix of a Segmentable type.
70  *
71  * @signature TPrefix prefix(s, endPos);
72  *
73  * @param[in] s      Segmentable sequence to return the prefix for (type <tt>TSeq</tt>).
74  * @param[in] endPos End position must be convertible to <tt>Position&lt;TSeq&gt;::Type</tt>.
75  *
76  * @return TPrefix The prefix of length <tt>endPos</tt>.  Type as returned by @link SegmentableConcept#Prefix @endlink
77  *                 for TSeq.
78  */
79 
80 /*!
81  * @mfn SegmentableConcept#Infix
82  * @brief Returns infix type in a flattening fashion.
83  *
84  * @signature Infix<TSeq>::Type
85  *
86  * @tparam TSeq The segmentable sequence type to get infix type for.
87  * @return Type The infix type.
88  *
89  * The infix any segment is an infix.
90  */
91 
92 /*!
93  * @fn SegmentableConcept#infixWithLength
94  * @brief Returns the infix of a Segmentable type.
95  *
96  * @signature TInfix infixWithLength(s, beginPos, len);
97  *
98  * @param[in] s        Segmentable sequence to return the infix for (type <tt>TSeq</tt>).
99  * @param[in] beginPos Begin position must be convertible to <tt>Position&lt;TSeq&gt;::Type</tt>.
100  * @param[in] len      Length of the prefix, must be convertible to <tt>Size&lt;TSeq&gt;::Type</tt>.
101  *
102  * Equivalent to <tt>infix(s, beginPos, beginPos + len)</tt>.
103  *
104  * @aka substr
105  */
106 
107 /*!
108  * @fn SegmentableConcept#infix
109  * @brief Returns the infix of a Segmentable type.
110  *
111  * @signature TInfix infix(s, beginPos, endPos);
112  *
113  * @param[in] s        Segmentable sequence to return the infix for (type <tt>TSeq</tt>).
114  * @param[in] beginPos Begin position must be convertible to <tt>Position&lt;TSeq&gt;::Type</tt>.
115  * @param[in] endPos   End position must be convertible to <tt>Position&lt;TSeq&gt;::Type</tt>.
116  *
117  * @aka substr
118  */
119 
120 /*!
121  * @mfn SegmentableConcept#Suffix
122  * @brief Returns suffix type in a flattening fashion.
123  *
124  * @signature Suffix<TSeq>::Type
125  *
126  * @tparam TSeq The segmentable sequence type to get suffix type for.
127  * @return Type The suffix type.
128  *
129  * The suffix type of a suffix is a suffix, the suffix of any other segment type is an infix.
130  */
131 
132 /*!
133  * @fn SegmentableConcept#suffix
134  * @brief Returns the suffix of a Segmentable type.
135  *
136  * @signature TSuffix suffix(s, beginPos);
137  *
138  * @param[in] s        The segmentable type to get the suffix of.
139  * @param[in] beginPos Begin position must be convertible to <tt>Position&lt;TSeq&gt;::Type</tt>.
140  *
141  * @return TSuffix The suffix type as returned by @link SegmentableConcept#Suffix @endlink.
142  */
143 
144 //////////////////////////////////////////////////////////////////////////////
145 // Segment
146 //////////////////////////////////////////////////////////////////////////////
147 
148 // TODO(holtgrew): We need to document how to get reference/pointer type of segments.
149 
150 /*!
151  * @class Segment
152  * @implements RandomAccessContainerConcept
153  * @implements SegmentableConcept
154  * @headerfile <seqan/sequence.h>
155  * @brief A contiguous part of a sequence.
156  *
157  * @signature template <typename THost, typename TSpec>
158  *            class Segment;
159  *
160  * @tparam THost The underlying @link ContainerConcept sequence @endlink type.
161  * @tparam TSpec The tag to use for selecting the Segment specialization.
162  *
163  * Segments are lightweight representations of an underlying sequence (host).  Only a pointer to the host and begin
164  * and/or end position have to be stored.
165  *
166  * Segments support element access (reading and writing) as well as random access iteration.
167  *
168  * @snippet demos/dox/sequence/segment.cpp basic operations
169  *
170  * You can get the type of the infix/prefix/suffix of a sequence using @link SegmentableConcept#Infix @endlink,
171  * @link SegmentableConcept#Prefix @endlink, and @link SegmentableConcept#Suffix @endlink.  These metafunctions will
172  * "flatten" the type such that using these metafunctions, the infix of an infix is an infix and not
173  * an Infix Segment with an Infix Segment as its host.  Instead, it will again be an Infix Segment
174  * of the host of the inner type.
175  *
176  * A suffix of a suffix remains a suffix, a prefix of a prefix remains a prefix.  Any other combination leads to
177  * the resulting type being a infix segment.
178  *
179  * @snippet demos/dox/sequence/segment.cpp metafunction examples
180  *
181  * If you explicitely need a segment and keep the underlying sequence as it is, explicitely use the <tt>Segment</tt>
182  * template class.
183  *
184  * @snippet demos/dox/sequence/segment.cpp explicit segment
185  *
186  * @aka substring
187  */
188 
189 /*!
190  * @fn Segment#beginPosition
191  * @headerfile <seqan/sequence.h>
192  * @brief Return segment's begin position.
193  *
194  * @signature TPos beginPosition(seg);
195  *
196  * @param[in] seg The Segment to query for its begin position.
197  *
198  * @return TPos The begin position of the segment.  TPos is the position type of the Segment as returned by
199  *              @link ContainerConcept#Position Position @endlink.
200  */
201 
202 /*!
203  * @fn Segment#endPosition
204  * @headerfile <seqan/sequence.h>
205  * @brief Return segment's end position.
206  *
207  * @signature TPos endPosition(seg);
208  *
209  * @param[in] seg The Segment to query for its end position.
210  *
211  * @return TPos The end position of the segment.  TPos is the position type of the Segment as returned by
212  *              @link ContainerConcept#Position Position @endlink.
213  */
214 
215 struct InfixSegment {};
216 
217 template <typename THost, typename TSpec = InfixSegment>
218 class Segment
219 {
220 };
221 
222 //////////////////////////////////////////////////////////////////////////////
223 
224 template <typename THost, typename TSpec>
225 struct Host<Segment<THost, TSpec> >
226 {
227     typedef THost Type;
228 };
229 
230 template <typename THost, typename TSpec>
231 struct Host<Segment<THost, TSpec> const >
232 {
233     typedef THost Type;
234 };
235 
236 //////////////////////////////////////////////////////////////////////////////
237 
238 template <typename THost, typename TSpec>
239 struct Pointer_<Segment<THost, TSpec> >
240 {
241     typedef Segment<THost, TSpec> Type;
242 };
243 
244 template <typename THost, typename TSpec>
245 struct Pointer_<Segment<THost, TSpec> const >
246 {
247     typedef Segment<THost, TSpec> Type;
248 };
249 
250 //////////////////////////////////////////////////////////////////////////////
251 
252 template <typename THost, typename TSpec>
253 struct Parameter_<Segment<THost, TSpec> >
254 {
255     typedef Segment<THost, TSpec> Type;
256 };
257 
258 template <typename THost, typename TSpec>
259 struct Parameter_<Segment<THost, TSpec> const >
260 {
261     typedef Segment<THost, TSpec> Type;
262 };
263 
264 //////////////////////////////////////////////////////////////////////////////
265 
266 template <typename THost, typename TSpec>
267 struct Spec<Segment<THost, TSpec> >
268 {
269     typedef TSpec Type;
270 };
271 
272 template <typename THost, typename TSpec>
273 struct Spec<Segment<THost, TSpec> const>
274 {
275     typedef TSpec Type;
276 };
277 
278 // ----------------------------------------------------------------------------
279 // Metafunction StringSpec
280 // ----------------------------------------------------------------------------
281 
282 template <typename T>
283 struct StringSpec;
284 
285 template <typename THost, typename TSpec>
286 struct StringSpec<Segment<THost, TSpec> > : StringSpec<THost> {};
287 
288 //////////////////////////////////////////////////////////////////////////////
289 
290 template <typename THost, typename TSpec>
291 struct Value<Segment<THost, TSpec> > :
292     Value<THost> {};
293 
294 template <typename THost, typename TSpec>
295 struct Value<Segment<THost, TSpec> const > :
296     Value<THost> {};
297 
298 //////////////////////////////////////////////////////////////////////////////
299 
300 template <typename THost, typename TSpec>
301 struct GetValue<Segment<THost, TSpec> > :
302     GetValue<THost> {};
303 
304 template <typename THost, typename TSpec>
305 struct GetValue<Segment<THost, TSpec> const > :
306     GetValue<THost> {};
307 
308 //////////////////////////////////////////////////////////////////////////////
309 
310 template <typename THost, typename TSpec>
311 struct Reference<Segment<THost, TSpec> > :
312     Reference<THost> {};
313 
314 template <typename THost, typename TSpec>
315 struct Reference<Segment<THost, TSpec> const > :
316     Reference<THost> {};
317 
318 // TODO(weese): It's a philosophical question whether const Views like Segments are allowed to modify the host or not
319 //              It would be more restrictive but consistent in generic algorithms if Segments would behave like Strings (immutable host)
320 //              On the other hand segments are prone to unintentionally be given as a const to a function (by-const-reference, not by copy)
321 
322 //template <typename THost, typename TSpec>
323 //struct Reference<Segment<THost, TSpec> const > :
324 //    Reference<THost const> {};
325 
326 //////////////////////////////////////////////////////////////////////////////
327 
328 // TODO(holtgrew): Should the iterators of const segments be iterators with the constness of the host.
329 
330 template <typename THost, typename TSpec>
331 struct Iterator<Segment<THost, TSpec>, Rooted>
332 {
333     typedef Segment<THost, TSpec> TSequence_;
334     typedef typename Iterator<THost, Standard>::Type TIterator_;
335     typedef Iter<TSequence_, AdaptorIterator<TIterator_> > Type;
336 };
337 template <typename THost, typename TSpec>
338 struct Iterator<Segment<THost, TSpec> const, Rooted>
339 {
340     typedef Segment<THost, TSpec> TSequence_;
341     typedef typename Iterator<THost, Standard>::Type TIterator_;
342     typedef Iter<TSequence_, AdaptorIterator<TIterator_> > Type;
343 };
344 
345 template <typename THost, typename TSpec>
346 struct Iterator<Segment<THost, TSpec>, Standard>:
347     Iterator<THost, Standard> {};
348 
349 template <typename THost, typename TSpec>
350 struct Iterator<Segment<THost, TSpec> const, Standard>:
351     Iterator<THost , Standard> {};
352 
353 
354 
355 //////////////////////////////////////////////////////////////////////////////
356 
357 template <typename THost, typename TSpec>
358 struct Size<Segment<THost, TSpec> > :
359     Size<THost> {};
360 
361 template <typename THost, typename TSpec>
362 struct Size<Segment<THost, TSpec> const > :
363     Size<THost> {};
364 
365 template <typename THost, typename TSpec>
366 struct Position<Segment<THost, TSpec> > :
367     Position<THost> {};
368 
369 template <typename THost, typename TSpec>
370 struct Position<Segment<THost, TSpec> const > :
371     Position<THost> {};
372 
373 //////////////////////////////////////////////////////////////////////////////
374 
375 template <typename THost, typename TSpec>
376 struct DefaultOverflowImplicit<Segment<THost, TSpec > > :
377     DefaultOverflowImplicit<THost> {};
378 
379 template <typename THost, typename TSpec>
380 struct DefaultOverflowImplicit<Segment<THost, TSpec > const > :
381     DefaultOverflowImplicit<THost> {};
382 
383 //////////////////////////////////////////////////////////////////////////////
384 
385 template <typename THost, typename TSpec>
386 struct DefaultOverflowExplicit<Segment<THost, TSpec > > :
387     DefaultOverflowExplicit<THost> {};
388 
389 template <typename THost, typename TSpec>
390 struct DefaultOverflowExplicit<Segment<THost, TSpec > const > :
391     DefaultOverflowExplicit<THost> {};
392 
393 //////////////////////////////////////////////////////////////////////////////
394 
395 template <typename THost, typename TSpec>
396 struct IsContiguous< Segment<THost, TSpec> > :
397     IsContiguous<THost> {};
398 
399 //////////////////////////////////////////////////////////////////////////////
400 
401 template <typename THost, typename TSpec>
402 struct IsSequence< Segment<THost, TSpec> > :
403     True {};
404 
405 // ----------------------------------------------------------------------------
406 // Concept ContainerConcept
407 // ----------------------------------------------------------------------------
408 
409 template <typename THost, typename TSpec>
410 SEQAN_CONCEPT_IMPL((Segment<THost, TSpec>), (ContainerConcept));
411 
412 template <typename THost, typename TSpec>
413 SEQAN_CONCEPT_IMPL((Segment<THost, TSpec> const), (ContainerConcept));
414 
415 //////////////////////////////////////////////////////////////////////////////
416 
417 template <typename THost, typename TSpec>
418 struct IsLightWeight< Segment<THost, TSpec> > :
419     True {};
420 
421 
422 //////////////////////////////////////////////////////////////////////////////
423 
424 //////////////////////////////////////////////////////////////////////////////
425 // functions for all Segment classes
426 //////////////////////////////////////////////////////////////////////////////
427 
428 template <typename THost, typename TSpec>
429 inline void const *
430 getObjectId(Segment<THost, TSpec> const & me)
431 {
432     return getObjectId(host(me));
433 }
434 
435 // --------------------------------------------------------------------------
436 // Function _toPointer()
437 // --------------------------------------------------------------------------
438 
439 template <typename THost, typename TSpec>
440 inline typename Pointer_<Segment<THost, TSpec> >::Type
441 _toPointer(Segment<THost, TSpec> & me)
442 {
443     return me;
444 }
445 
446 template <typename THost, typename TSpec>
447 inline typename Pointer_<Segment<THost, TSpec> const >::Type
448 _toPointer(Segment<THost, TSpec> const & me)
449 {
450     return me;
451 }
452 
453 // --------------------------------------------------------------------------
454 // Function _fromPointer()
455 // --------------------------------------------------------------------------
456 
457 template <typename THost, typename TSpec>
458 Segment<THost, TSpec> _fromPointer(Segment<THost, TSpec> & me)
459 {
460     return me;
461 }
462 
463 template <typename THost, typename TSpec>
464 Segment<THost, TSpec> _fromPointer(Segment<THost, TSpec> const & me)
465 {
466     return me;
467 }
468 
469 
470 //////////////////////////////////////////////////////////////////////////////
471 
472 template <typename THost, typename TSpec>
473 inline bool
474 empty(Segment<THost, TSpec> const & me)
475 {
476     return (beginPosition(me) == endPosition(me));
477 }
478 
479 //////////////////////////////////////////////////////////////////////////////
480 
481 template <typename THost, typename TSpec>
482 inline typename Size<Segment<THost, TSpec> const>::Type
483 length(Segment<THost, TSpec> const & me)
484 {
485     return endPosition(me) - beginPosition(me);
486 }
487 
488 //////////////////////////////////////////////////////////////////////////////
489 
490 template <typename THost, typename TSpec>
491 inline typename Size< Segment<THost, TSpec> const>::Type
492 capacity(Segment<THost, TSpec> const & me)
493 {
494     return capacity(host(me)) + length(me) - length(host(me));
495 }
496 
497 //////////////////////////////////////////////////////////////////////////////
498 //////////////////////////////////////////////////////////////////////////////
499 
500 template <typename THost, typename TSpec>
501 inline bool
502 hasNoHost(Segment<THost, TSpec> const & target)
503 {
504     return !_toPointer(host(target));
505 }
506 
507 
508 //////////////////////////////////////////////////////////////////////////////
509 
510 // operationToSet testet, ob statt einer assign/append-Funktion
511 // eine set Funktion aufgerufen werden soll. Das ist nur dann der Fall,
512 // wenn target keinen Host hat und source einen kompatiblen Host
513 // anbietet.
514 // returns true:  set Funktion verwendet,
515 //                wurde bereits von test_operation_2_set gemacht
516 // returns false: keine set Funktion verwenden
517 //                muss noch assign/append gemacht werden.
518 
519 template <typename TSameSpec, typename TTargetInfix>
520 struct SegmentSetImpl_
521 {
522     template <typename TTarget, typename TSource>
523     static inline bool operationToSet(TTarget &, TSource &)
524     {
525         return false;
526     }
527 };
528 
529 template <typename TTargetInfix>
530 struct SegmentSetImpl_<True, TTargetInfix>
531 {
532     template <typename TTarget, typename TSource>
533     static inline bool operationToSet(TTarget & target, TSource & source)
534     {
535         set(target, source);
536         return true;
537     }
538 };
539 
540 template <>
541 struct SegmentSetImpl_<False, True>
542 {
543     template <typename TTarget, typename TSource>
544     static inline bool operationToSet(TTarget & target, TSource & source)
545     {
546         set(target, host(source), beginPosition(source), endPosition(source));
547         return true;
548     }
549 };
550 
551 //////////////////////////////////////////////////////////////////////////////
552 // assign
553 //////////////////////////////////////////////////////////////////////////////
554 
555 // TODO(holtgrew): We'd rather only have one version.
556 
557 template<typename THost, typename TSpec>
558 inline void
559 assign(Segment<THost, TSpec> & target,
560        Segment<THost, TSpec> const & source)
561 {
562     typedef Segment<THost, TSpec> TSegment;
563     assign(target, source, typename DefaultOverflowImplicit<TSegment>::Type());
564 }
565 
566 template<typename THost, typename TSpec>
567 inline void
568 assign(Segment<THost, TSpec> & target,
569        Segment<THost, TSpec> & source)
570 {
571     typedef Segment<THost, TSpec> TSegment;
572     assign(target, source, typename DefaultOverflowImplicit<TSegment>::Type());
573 }
574 
575 //////////////////////////////////////////////////////////////////////////////
576 
577 template <typename TExpand>
578 struct AssignSegment_
579 {
580     template <typename THost, typename TSpec, typename TSource>
581     static inline void
582     assign_(
583         Segment<THost const, TSpec> & target,
584         TSource & source)
585     {
586         set(target, source);
587     }
588 
589     template <typename THost, typename TSpec, typename TSource>
590     static inline void
591     assign_(
592         Segment<THost const, TSpec> & target,
593         TSource & source,
594         typename Size< Segment<THost const, TSpec> >::Type /*limit*/)
595     {
596         set(target, source);
597     }
598 
599     template <typename THost, typename TSpec, typename TSource>
600     static inline void
601     assign_(
602         Segment<THost, TSpec> & target,
603         TSource & source)
604     {
605         set(target, source);
606     }
607 
608     template <typename THost, typename TSpec, typename TSource>
609     static inline void
610     assign_(
611         Segment<THost, TSpec> & target,
612         TSource & source,
613         typename Size< Segment<THost, TSpec> >::Type limit)
614     {
615         (void)limit;
616         set(target, source);
617     }
618 
619     template <typename THost, typename TSpec, typename TSource>
620     static inline void
621     assign_(
622         Segment<THost, TSpec> const & target,
623         TSource & source)
624     {
625         set(target, source);
626     }
627 
628     template <typename THost, typename TSpec, typename TSource>
629     static inline void
630     assign_(
631         Segment<THost, TSpec> const & target,
632         TSource & source,
633         typename Size< Segment<THost, TSpec> >::Type limit)
634     {
635         (void)limit;
636         set(target, source);
637     }
638 };
639 
640 //____________________________________________________________________________
641 
642 template <typename THost, typename TSpec, typename TSource, typename TExpand>
643 inline void
644 assign(Segment<THost, TSpec> & target,
645        TSource & source,
646        Tag<TExpand>)
647 {
648     AssignSegment_<Tag<TExpand> >::assign_(target, source);
649 }
650 template <typename THost, typename TSpec, typename TSource, typename TExpand>
651 inline void
652 assign(Segment<THost, TSpec> & target,
653        TSource const & source,
654        Tag<TExpand>)
655 {
656     AssignSegment_<Tag<TExpand> >::assign_(target, source);
657 }
658 
659 template <typename THost, typename TSpec, typename TSource, typename TExpand>
660 inline void
661 assign(Segment<THost, TSpec> & target,
662        TSource & source,
663        typename Size< Segment<THost, TSpec> >::Type limit,
664        Tag<TExpand>)
665 {
666     AssignSegment_<Tag<TExpand> >::assign_(target, source, limit);
667 }
668 template <typename THost, typename TSpec, typename TSource, typename TExpand>
669 inline void
670 assign(Segment<THost, TSpec> & target,
671        TSource const & source,
672        typename Size< Segment<THost, TSpec> >::Type limit,
673        Tag<TExpand>)
674 {
675     AssignSegment_<Tag<TExpand> >::assign_(target, source, limit);
676 }
677 
678 //(for temporary targets)
679 
680 template <typename THost, typename TSpec, typename TSource, typename TExpand>
681 inline void
682 assign(Segment<THost, TSpec> const & target,
683        TSource & source,
684        Tag<TExpand>)
685 {
686     AssignSegment_<Tag<TExpand> >::assign_(target, source);
687 }
688 template <typename THost, typename TSpec, typename TSource, typename TExpand>
689 inline void
690 assign(Segment<THost, TSpec> const & target,
691        TSource const & source,
692        Tag<TExpand>)
693 {
694     AssignSegment_<Tag<TExpand> >::assign_(target, source);
695 }
696 
697 template <typename THost, typename TSpec, typename TSource, typename TExpand>
698 inline void
699 assign(Segment<THost, TSpec> const & target,
700        TSource & source,
701        typename Size< Segment<THost, TSpec> >::Type limit,
702        Tag<TExpand>)
703 {
704     AssignSegment_<Tag<TExpand> >::assign_(target, source, limit);
705 }
706 template <typename THost, typename TSpec, typename TSource, typename TExpand>
707 inline void
708 assign(Segment<THost, TSpec> const & target,
709        TSource const & source,
710        typename Size< Segment<THost, TSpec> >::Type limit,
711        Tag<TExpand>)
712 {
713     AssignSegment_<Tag<TExpand> >::assign_(target, source, limit);
714 }
715 
716 //////////////////////////////////////////////////////////////////////////////
717 //////////////////////////////////////////////////////////////////////////////
718 
719 template <typename TLeftHost, typename TLeftSpec, typename TRight >
720 inline bool
721 operator == (Segment<TLeftHost, TLeftSpec> const & left,
722             TRight const & right)
723 {
724     typename Comparator<Segment<TLeftHost, TLeftSpec> >::Type _lex(left, right);
725     return isEqual(_lex);
726 }
727 
728 //////////////////////////////////////////////////////////////////////////////
729 
730 template <typename TLeftHost, typename TLeftSpec, typename TRight >
731 inline bool
732 operator != (Segment<TLeftHost, TLeftSpec> const & left,
733             TRight const & right)
734 {
735     typename Comparator<Segment<TLeftHost, TLeftSpec> >::Type _lex(left, right);
736     return isNotEqual(_lex);
737 }
738 
739 //////////////////////////////////////////////////////////////////////////////
740 
741 template <typename TLeftHost, typename TLeftSpec, typename TRight>
742 inline bool
743 operator < (Segment<TLeftHost, TLeftSpec> const & left,
744             TRight const & right)
745 {
746     return isLess(left, right, typename DefaultPrefixOrder<Segment<TLeftHost, TLeftSpec> >::Type());
747 }
748 
749 //////////////////////////////////////////////////////////////////////////////
750 
751 template <typename TLeftHost, typename TLeftSpec, typename TRight>
752 inline bool
753 operator <= (Segment<TLeftHost, TLeftSpec> const & left,
754              TRight const & right)
755 {
756     return isLessOrEqual(left, right, typename DefaultPrefixOrder<Segment<TLeftHost, TLeftSpec> >::Type());
757 }
758 //////////////////////////////////////////////////////////////////////////////
759 
760 template <typename TLeftHost, typename TLeftSpec, typename TRight>
761 inline bool
762 operator > (Segment<TLeftHost, TLeftSpec> const & left,
763             TRight const & right)
764 {
765     return isGreater(left, right, typename DefaultPrefixOrder<Segment<TLeftHost, TLeftSpec> >::Type());
766 }
767 
768 //////////////////////////////////////////////////////////////////////////////
769 
770 template <typename TLeftHost, typename TLeftSpec, typename TRight>
771 inline bool
772 operator >= (Segment<TLeftHost, TLeftSpec> const & left,
773         TRight const & right)
774 {
775     return isGreaterOrEqual(left, right, typename DefaultPrefixOrder<Segment<TLeftHost, TLeftSpec> >::Type());
776 }
777 
778 
779 //////////////////////////////////////////////////////////////////////////////
780 // stream operators
781 //////////////////////////////////////////////////////////////////////////////
782 
783 template <typename TStream, typename THost, typename TSpec>
784 inline TStream &
785 operator << (TStream & target,
786              Segment<THost, TSpec> const & source)
787 {
788     typename DirectionIterator<TStream, Output>::Type it(target);
789     write(it, source);
790     return target;
791 }
792 
793 //////////////////////////////////////////////////////////////////////////////
794 
795 template <typename TStream, typename THost, typename TSpec>
796 inline TStream &
797 operator >> (TStream & source,
798              Segment<THost, TSpec> & target)
799 {
800     typename DirectionIterator<TStream, Input>::Type it(source);
801     read(it, target);
802     return source;
803 }
804 template <typename TStream, typename THost, typename TSpec>
805 inline TStream &
806 operator >> (TStream & source,
807              Segment<THost, TSpec> const & target)
808 {
809     typename DirectionIterator<TStream, Input>::Type it(source);
810     read(it, target);
811     return source;
812 }
813 
814 //////////////////////////////////////////////////////////////////////////////
815 
816 // this function doesn't do anything as we are not allowed to change the host (only its elements)
817 // it is, however, implemented for algorithms that get a sequence to work on
818 // and need to make sure that it has a certain length
819 
820 template <typename THost, typename TSpec, typename TSize, typename TExpand>
821 inline typename Size< Segment<THost, TSpec> >::Type
822 resize(
823     Segment<THost, TSpec> & me,
824     TSize new_length,
825     Tag<TExpand>)
826 {
827     ignoreUnusedVariableWarning(new_length);
828 
829     SEQAN_ASSERT_EQ(new_length, length(me));
830     return length(me);
831 }
832 
833 //////////////////////////////////////////////////////////////////////////////
834 
835 // TODO(singer): moveValue still works. Should make the compiler throw an error.
836 
837 } //namespace seqan
838 
839 #endif //#ifndef SEQAN_HEADER_...
840