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: David Weese <david.weese@fu-berlin.de>
33 // ==========================================================================
34 
35 #ifndef SEQAN_HEADER_PIPE_BASE_H
36 #define SEQAN_HEADER_PIPE_BASE_H
37 
38 namespace seqan {
39 
40     // shortcuts to ease pipeline construction
41     #define TypeOf_(TObject)  typename Value<TObject>::Type
42     #define TSizeOf_(TObject) typename Size<TObject>::Type
43 
44 /*!
45  * @class Pipe
46  * @headerfile <seqan/pipe.h>
47  * @brief Pipes are pop-passive pipeline modules.
48  *
49  * @signature template <typename TInput, typename TSpec>
50  *            class Pipe;
51  *
52  * @tparam TSpec  The specializing type.
53  * @tparam TInput The type of the pipeline module this module reads from.  Use Bundle2, Bundle3, etc. to read
54  *                from more than one module.
55  *
56  * Use @link Pipe#Value @endlink to get the output type of a given Pipe (returns <tt>Value&lt;TInput&gt;::Type</tt> by
57  * default).
58  *
59  * Use Size to get the size type of a given Pipe (returns <tt>Size&lt;TInput&gt;::Type</tt> by default).
60  */
61 
62 /*!
63  * @fn Pipe::Pipe
64  * @brief Constructor
65  *
66  * @signature Pipe::Pipe(in);
67  *
68  * @param[in] in Reference to an input pipe.
69  */
70 
71     template < typename TInput, typename TSpec >
72     struct Pipe {
73         TInput &in;
PipePipe74         Pipe(TInput &_in): in(_in) {}
75     };
76 
77     // base class for multiple sequence algorithms
78     // to hold extra information about desired position type (TPair)
79     // and the type storing absolute sequence offsets (TLimitsString)
80     template <typename TSpec, typename TPair, typename TLimitsString>
81     struct Multi;
82 
83 /*!
84  * @class Bundle2
85  * @headerfile <seqan/pipe.h>
86  * @brief Stores references to two arbitrary objects.
87  *
88  * @signature template <typename TInput1, typename TInput2>
89  *            class Bundle2;
90  *
91  * @tparam TInput1 The type of the first object.
92  * @tparam TInput2 The type of the second object.
93  *
94  * Primarily used as an adaptor for pipes with two sources.
95  *
96  * @see bundle2
97  *
98  * @var TInput1 Bundle2::in1;
99  * @brief TInput1 reference
100  *
101  * @var TInput2 Bundle2::in2;
102  * @brief TInput2 reference
103  */
104 
105     // pipe input adapter 2->1 pipe
106     template < typename TInput1, typename TInput2 >
107     struct Bundle2 {
108         typedef TInput1 Input1;
109         typedef TInput2 Input2;
110         TInput1 &in1;
111         TInput2 &in2;
Bundle2Bundle2112         Bundle2(TInput1 &_in1, TInput2 &_in2): in1(_in1),in2(_in2) {}
113     };
114 
115 /*!
116  * @fn bundle2
117  * @headerfile <seqan/pipe.h>
118  * @brief Returns a bundle of two objects.
119  *
120  * @signature TBundle bundle2(in1, in2);
121  *
122  * @param[in] in1 First object.
123  * @param[in] in2 Second object.
124  *
125  * @return TBundle A Bundle2 with references to <tt>in1</tt> and <tt>in2</tt>.
126  *
127  * @see Bundle2
128  */
129 
130     template < typename TInput1, typename TInput2 >
131     inline Bundle2< TInput1, TInput2 >
bundle2(TInput1 & _in1,TInput2 & _in2)132     bundle2(TInput1 &_in1, TInput2 &_in2) {
133         return Bundle2< TInput1, TInput2 >(_in1, _in2);
134     }
135 /*!
136  * @class Bundle3
137  *
138  * @brief Stores references to three arbitrary objects.
139  *
140  * @signature template <typename TInput1, typename TInput2, typename TInput3>
141  *            struct Bundle3;
142  *
143  * @tparam TInput3 The type of the third object.
144  * @tparam TInput2 The type of the second object.
145  * @tparam TInput1 The type of the first object.
146  *
147  * Primarily used as an adaptor for pipes with three sources.
148  *
149  * @see bundle3
150  *
151  * @var TInput1 Bundle3::in1;
152  * @brief TInput1 reference
153  *
154  * @var TInput2 Bundle3::in2;
155  * @brief TInput2 reference
156  *
157  * @var TInput3 Bundle3::in3;
158  * @brief TInput3 reference
159  */
160 
161     // pipe input adapter 3->1 pipe
162     template < typename TInput1, typename TInput2, typename TInput3 >
163     struct Bundle3 {
164         typedef TInput1 Input1;
165         typedef TInput2 Input2;
166         typedef TInput3 Input3;
167         TInput1 &in1;
168         TInput2 &in2;
169         TInput3 &in3;
Bundle3Bundle3170         Bundle3(TInput1 &_in1, TInput2 &_in2, TInput3 &_in3): in1(_in1),in2(_in2),in3(_in3) {}
171     };
172 
173 /*!
174  * @fn bundle3
175  * @headerfile <seqan/pipe.h>
176  * @brief Returns a bundle of three objects.
177  *
178  * @signature TBundle bundle3(in1, in2, in3);
179  *
180  * @param[in] in1 First object.
181  * @param[in] in2 Second object.
182  * @param[in] in3 Third object.
183  *
184  * @return TBundle A Bundle3 with references to <tt>in1</tt>, <tt>in2</tt>, and <tt>in3</tt>.
185  *
186  * @see Bundle3
187  */
188 
189     template < typename TInput1, typename TInput2, typename TInput3 >
190     inline Bundle3< TInput1, TInput2, TInput3 >
bundle3(TInput1 & _in1,TInput2 & _in2,TInput3 & _in3)191     bundle3(TInput1 &_in1, TInput2 &_in2, TInput3 &_in3) {
192         return Bundle3< TInput1, TInput2, TInput3 >(_in1, _in2, _in3);
193     }
194 
195 /*!
196  * @class Bundle5
197  * @headerfile <seqan/pipe.h>
198  * @brief Stores references to five arbitrary objects.
199  *
200  * @signature template <typename TInput1, typename TInput2, typename TInput3, typename TInput4, typename TInput5>
201  *            class Bundle5;
202  *
203  * @tparam TInput1 The type of the first object.
204  * @tparam TInput2 The type of the second object.
205  * @tparam TInput3 The type of the third object.
206  * @tparam TInput4 The type of the fourth object.
207  * @tparam TInput5 The type of the fifth object.
208  *
209  * Primarily used as an adaptor for pipes with five sources.
210  *
211  * @see bundle5
212  *
213  * @var TInput1 Bundle5::in1;
214  * @brief TInput1 reference
215  *
216  * @var TInput2 Bundle5::in2;
217  * @brief TInput2 reference
218  *
219  * @var TInput3 Bundle5::in3;
220  * @brief TInput3 reference
221  *
222  * @var TInput4 Bundle5::in4;
223  * @brief TInput4 reference
224  *
225  * @var TInput5 Bundle5::in5;
226  * @brief TInput5 reference
227  */
228 
229     // pipe input adapter 5->1 pipe
230     template < typename TIn1, typename TIn2, typename TIn3, typename TIn4, typename TIn5 >
231     struct Bundle5 {
232         TIn1 &in1; TIn2 &in2;
233         TIn3 &in3; TIn4 &in4;
234         TIn5 &in5;
Bundle5Bundle5235         Bundle5(TIn1& _in1, TIn2& _in2,
236                 TIn3& _in3, TIn4& _in4,
237                 TIn5& _in5):    in1(_in1),in2(_in2),
238                                 in3(_in3),in4(_in4),
239                                 in5(_in5) {}
240     };
241 
242 /*!
243  * @fn bundle5
244  * @headerfile <seqan/pipe.h>
245  * @brief Returns a bundle of five objects.
246  *
247  * @signature TBundle bundle5(in1, in2, in3, in4, in5);
248  *
249  * @param[in] in1 First object.
250  * @param[in] in2 Second object.
251  * @param[in] in3 Third object.
252  * @param[in] in4 Fourth object.
253  * @param[in] in5 Fifth object.
254  *
255  * @return TBundle A Bundle5 with references to <tt>in1</tt>, <tt>in2</tt>, <tt>in3</tt>, <tt>in4</tt>,
256  *                 and <tt>in5</tt>.
257  *
258  * @see Bundle5
259  */
260 
261     template < typename TIn1, typename TIn2, typename TIn3, typename TIn4, typename TIn5 >
262     inline Bundle5< TIn1, TIn2, TIn3, TIn4, TIn5 >
bundle5(TIn1 & _in1,TIn2 & _in2,TIn3 & _in3,TIn4 & _in4,TIn5 & _in5)263     bundle5(TIn1 &_in1, TIn2 &_in2, TIn3 &_in3, TIn4 &_in4, TIn5 &_in5) {
264         return Bundle5< TIn1, TIn2, TIn3, TIn4, TIn5 >(_in1, _in2, _in3, _in4, _in5);
265     }
266 
267     template < typename TValue, typename TSize >
268     struct AbstractSource {};
269 
270 /*!
271  * @mfn Pipe#Value
272  * @brief Return value type of the Pipe specialization.
273  *
274  * @signature Value<TPipe>::Type;
275  *
276  * @tparam TPipe The Pipe specialization to query.
277  *
278  * @return Type The resulting value type.
279  */
280 
281     template < typename TValue, typename TSize >
282     struct Value< Pipe<void, AbstractSource<TValue, TSize> > > {
283         typedef TValue Type;
284     };
285 
286 /*!
287  * @mfn Pipe#Size
288  * @brief Return size type of the Pipe specialization.
289  *
290  * @signature Size<TPipe>::Type;
291  *
292  * @tparam TPipe The Pipe specialization to query.
293  *
294  * @return Type The resulting size type.
295  */
296 
297     template < typename TValue, typename TSize >
298     struct Size< Pipe<void, AbstractSource<TValue, TSize> > > {
299         typedef TSize Type;
300     };
301 
302     template < typename TInput, typename TSpec >
303     struct Value< Pipe<TInput, TSpec> > {
304         typedef typename Value<TInput>::Type Type;
305     };
306 
307     template < typename TInput, typename TSpec >
308     struct Size< Pipe<TInput, TSpec> > {
309         typedef typename Size<TInput>::Type Type;
310     };
311 
312     template < typename TInput1, typename TInput2 >
313     struct Size< Bundle2< TInput1, TInput2 > > {
314         typedef typename Size<TInput1>::Type Type;
315     };
316 
317     template < typename TInput1, typename TInput2, typename TInput3 >
318     struct Size< Bundle3< TInput1, TInput2, TInput3 > > {
319         typedef typename Size<TInput1>::Type Type;
320     };
321 
322     template < typename TIn1, typename TIn2, typename TIn3, typename TIn4, typename TIn5 >
323     struct Size< Bundle5< TIn1, TIn2, TIn3, TIn4, TIn5 > > {
324         typedef typename Size<TIn1>::Type Type;
325     };
326 
327     template < typename TInput, typename TSpec >
328     struct Position< Pipe<TInput, TSpec> > {
329         typedef typename Size<Pipe<TInput, TSpec> >::Type Type;
330     };
331 
332     template < typename TInput, typename TSpec >
333     struct Difference< Pipe<TInput, TSpec> > {
334         typedef typename MakeSigned_<typename Size<Pipe<TInput, TSpec> >::Type>::Type Type;
335     };
336 /*
337     template < typename TInput, typename TSpec >
338     struct Iterator< Pipe<TInput, TSpec> >;
339 
340     template < typename TInput, typename TSpec >
341     struct Iterator< Pipe<TInput, TSpec> const >:
342         Iterator< Pipe<TInput, TSpec> > {};
343 */
344 
345     template <typename T>
346     struct Source;
347 
348     template <typename TInput, typename TSpec>
349     struct Source<Pipe<TInput, TSpec> >
350     {
351         typedef TInput Type;
352     };
353 
354     template < typename TInput, typename TSpec >
355     inline TInput const &
356     source(Pipe<TInput, TSpec> const &me) {
357         return me.in;
358     }
359 
360     template < typename TInput, typename TSpec >
361     inline TInput &
362     source(Pipe<TInput, TSpec> &me) {
363         return me.in;
364     }
365 
366 /*!
367  * @fn Pipe#length
368  * @headerfile <seqan/pipe.h>
369  * @brief Length of the pipe.
370  *
371  * @signature TSize length(pipe);
372  *
373  * @param[in] pipe  The Pipe to query for its size.
374  *
375  * @return    TSize The size of the pipe.
376  */
377 
378     template < typename TInput, typename TSpec >
379     inline typename Size< Pipe<TInput, TSpec> >::Type
380     length(Pipe<TInput, TSpec> const &me) {
381         return length(me.in);
382     }
383 
384     template < typename TInput1, typename TInput2 >
385     inline typename Size< Bundle2<TInput1, TInput2> >::Type
386     length(Bundle2<TInput1, TInput2> const &me) {
387         return length(me.in1);
388     }
389 
390     template < typename TInput1, typename TInput2, typename TInput3 >
391     inline typename Size< Bundle3<TInput1, TInput2, TInput3> >::Type
392     length(Bundle3<TInput1, TInput2, TInput3> const &me) {
393         return length(me.in1);
394     }
395 
396     template < typename TIn1, typename TIn2, typename TIn3, typename TIn4, typename TIn5 >
397     inline typename Size< Bundle5<TIn1, TIn2, TIn3, TIn4, TIn5> >::Type
398     length(Bundle5<TIn1, TIn2, TIn3, TIn4, TIn5> const &me) {
399         return length(me.in1);
400     }
401 
402 //////////////////////////////////////////////////////////////////////////////
403 
404 
405     template < typename TInput, typename TSpec >
406     inline typename Size< Pipe<TInput, TSpec> >::Type
407     countSequences(Pipe<TInput, TSpec> const &me) {
408         return countSequences(me.in);
409     }
410 
411     template < typename TInput1, typename TInput2 >
412     inline typename Size< Bundle2<TInput1, TInput2> >::Type
413     countSequences(Bundle2<TInput1, TInput2> const &me) {
414         return countSequences(me.in1);
415     }
416 
417     template < typename TInput1, typename TInput2, typename TInput3 >
418     inline typename Size< Bundle3<TInput1, TInput2, TInput3> >::Type
419     countSequences(Bundle3<TInput1, TInput2, TInput3> const &me) {
420         return countSequences(me.in1);
421     }
422 
423     template < typename TIn1, typename TIn2, typename TIn3, typename TIn4, typename TIn5 >
424     inline typename Size< Bundle5<TIn1, TIn2, TIn3, TIn4, TIn5> >::Type
425     countSequences(Bundle5<TIn1, TIn2, TIn3, TIn4, TIn5> const &me) {
426         return countSequences(me.in1);
427     }
428 
429 /*!
430  * @fn Pipe#front
431  * @headerfile <seqan/pipe.h>
432  * @brief Gets the first element of the remaining stream.
433  *
434  * @signature TValue front(object);
435  *
436  * @param[in] object A pop-passive pipeline module.
437  *
438  * @return TValue The first element of the remaining input stream.  Return type is <tt>Value&lt;TObject&gt;::Type</tt>
439  *                for <tt>object</tt> type <tt>TObject</tt>.
440  *
441  * Pipe#front or Pipe#pop can only be called within a read process surrounded by beginRead and endRead.
442  *
443  * @see Pipe#pop
444  */
445 
446     template < typename TInput, typename TSpec, typename TValue >
447     inline typename Value< Pipe<TInput, TSpec> >::Type const &
448     front(Pipe<TInput, TSpec> &me) {
449         return *me;
450     }
451 
452 /*!
453  * @fn Pipe#pop
454  * @headerfile <seqan/pipe.h>
455  * @brief Pops the first element of the remaining stream.
456  *
457  * @signature void pop(pipe[, ref]);
458  *
459  * @param[in,out] pipe A pop-passive pipeline module.
460  * @param[out]    ref    Reference to the result.  Result type is <tt>Value&lt;TObject&gt;::Type</tt> for <tt>object</tt>
461  *                       type <tt>TObject</tt>.  Returns the first element of the remaining input stream.
462  *
463  * In contrast to Pipe#front this function also steps one element further.
464  *
465  * Pipe#front or Pipe#pop can only be called within a read process surrounded by beginRead and endRead.
466  */
467 
468     template < typename TInput, typename TSpec, typename TValue >
469     inline void pop(Pipe<TInput, TSpec> &me, TValue &Ref_) {
470         Ref_ = *me;
471         ++me;
472     }
473 
474     template < typename TInput, typename TSpec >
475     inline void pop(Pipe<TInput, TSpec> &me) {
476         ++me;
477     }
478 
479 /*!
480  * @fn Pipe#atEnd
481  * @brief Check whether the @link Pipe @endlink object is at end.
482  *
483  * @signature bool atEnd(pipe);
484  *
485  * @param[in] pipe The @link Pipe @endlink object to query.
486  *
487  * @return bool true in case of the pipe being at the end, false otherwise.
488  */
489 
490     //////////////////////////////////////////////////////////////////////////////
491     // pipe flow control
492 
493     struct ControlEof_;            // end of stream
494     struct ControlEos_;            // end of sequence (for multiple sequences)
495     struct ControlClear_;        // clear previous pool
496     struct ControlBeginRead_;    // begin read process
497     struct ControlEndRead_;        // end read process
498 
499     typedef Tag<ControlEof_>        ControlEof;
500     typedef Tag<ControlEos_>        ControlEos;
501     typedef Tag<ControlClear_>        ControlClear;
502     typedef Tag<ControlBeginRead_>    ControlBeginRead;
503     typedef Tag<ControlEndRead_>    ControlEndRead;
504 
505     template < typename TInput, typename TSpec, typename TCommand >
506     inline bool control(Pipe<TInput, TSpec> &me, TCommand const &command) {
507         return control(me.in, command);
508     }
509 
510     template < typename TInput, typename TSpec >
511     inline bool eof(Pipe<TInput, TSpec> &me) {
512         return control(me, ControlEof());
513     }
514 
515     template < typename TInput, typename TSpec >
516     inline bool eos(Pipe<TInput, TSpec> &me) {
517         return control(me, ControlEos());
518     }
519 
520     template < typename TInput, typename TSpec >
521     inline bool clear(Pipe<TInput, TSpec> &me) {
522         return control(me, ControlClear());
523     }
524 
525 /*!
526  * @fn Pipe#beginRead
527  * @headerfile <seqan/pipe.h>
528  * @brief Initiates a read process.
529  *
530  * @signature bool beginRead(object);
531  *
532  * @param[in,out] object A pop-passive pipeline module.
533  *
534  * @return bool true on success, false on failure.
535  *
536  * <tt>beginRead</tt> rewinds the output stream, prepares <tt>object</tt> for succeeding reads, and typically calls
537  * <tt>beginRead</tt> of the input pipeline modules.
538  *
539  * A read process must be terminated with endRead. Nested read processes are not allowed.
540  *
541  * @see Pipe#endRead
542  */
543 
544     template < typename TInput, typename TSpec >
545     inline bool beginRead(Pipe<TInput, TSpec> &me)
546     {
547         return control(me, ControlBeginRead());
548     }
549 
550 /*!
551  * @fn Pipe#endRead
552  * @headerfile <seqan/pipe.h>
553  * @brief Terminates a read process.
554  *
555  * @signature bool endRead(object);
556  *
557  * @param[in,out] object A pop-passive pipeline module.
558  *
559  * @return bool true on success, false on failure.
560  *
561  * <tt>endRead</tt> closes the output stream, frees resources possibly allocated by beginRead, and typically calls
562  * <tt>endRead</tt> of the input pipeline modules.
563  *
564  * @see Pipe#beginRead
565  */
566 
567     template < typename TInput, typename TSpec >
568     inline bool endRead(Pipe<TInput, TSpec> &me) {
569         return control(me, ControlEndRead());
570     }
571 
572 
573     //////////////////////////////////////////////////////////////////////////////
574     // 2->1 pipe flow control
575     template < typename TInput1, typename TInput2, typename TCommand >
576     inline bool control(Bundle2<TInput1, TInput2> &me, TCommand const &command) {
577         return    control(me.in1, command) &&
578                 control(me.in2, command);
579     }
580 
581     //////////////////////////////////////////////////////////////////////////////
582     // 3->1 pipe flow control
583     template < typename TInput1, typename TInput2, typename TInput3, typename TCommand >
584     inline bool control(Bundle3<TInput1, TInput2, TInput3> &me, TCommand const &command) {
585         return    control(me.in1, command) &&
586                 control(me.in2, command) &&
587                 control(me.in3, command);
588     }
589 
590     //////////////////////////////////////////////////////////////////////////////
591     // 5->1 pipe flow control
592     template < typename TIn1, typename TIn2, typename TIn3, typename TIn4, typename TIn5, typename TCommand >
593     inline bool control(Bundle5<TIn1, TIn2, TIn3, TIn4, TIn5 > &me, TCommand const &command) {
594         return    control(me.in1, command) &&
595                 control(me.in2, command) &&
596                 control(me.in3, command) &&
597                 control(me.in4, command) &&
598                 control(me.in5, command);
599     }
600 /*!
601  * @fn Pipe#assign
602  * @headerfile <seqan/pipe.h>
603  * @brief Assigns one object to another object.
604  *
605  * @signature void assign(target, source);
606  *
607  * @param[out] target Reference to assign to.
608  * @param[in]  source Value to assign.
609  *
610  * Assign value of source to target.
611  */
612     //////////////////////////////////////////////////////////////////////////////
613     // pipe -> string
614 
615     // We cannot use the most-generic TObject as first argument, as operator << specialized somewhere else in
616     // the first argument and here we need to specialize it in the second.
617     template < typename TValue,
618                typename TStringSpec,
619                typename TInput,
620                typename TSpec >
621     inline void assign(String<TValue, TStringSpec> &dest, Pipe<TInput, TSpec> &src)
622     {
623         typedef typename Iterator<String<TValue, TStringSpec>, Standard >::Type TDestIter;
624         resize(dest, length(src));
625         beginRead(src);
626         for (TDestIter _cur = begin(dest, Standard()), _end = end(dest, Standard()); _cur != _end; ++_cur, ++src)
627             *_cur = *src;
628         endRead(src);
629     }
630 
631     template < typename TValue,
632                typename TSegmentSpec,
633                typename TInput,
634                typename TSpec >
635     inline void assign(Segment<TValue, TSegmentSpec> &dest, Pipe<TInput, TSpec> &src)
636     {
637         typedef typename Iterator<Segment<TValue, TSegmentSpec>, Standard >::Type TDestIter;
638         resize(dest, length(src));
639         beginRead(src);
640         for (TDestIter _cur = begin(dest, Standard()), _end = end(dest, Standard()); _cur != _end; ++_cur, ++src)
641             *_cur = *src;
642         endRead(src);
643     }
644 
645     template < typename TValue,
646                typename TStringSpec,
647                typename TInput,
648                typename TSpec >
649     inline void operator << (String<TValue, TStringSpec> &dest, Pipe<TInput, TSpec> &src)
650     {
651         assign(dest, src);
652     }
653 
654     template < typename TValue,
655                typename TSegmentSpec,
656                typename TInput,
657                typename TSpec >
658     inline void operator << (Segment<TValue, TSegmentSpec> &dest, Pipe<TInput, TSpec> &src)
659     {
660         assign(dest, src);
661     }
662 
663     //////////////////////////////////////////////////////////////////////////////
664     // pipe -> out_stream
665     template <typename TInput, typename TSpec>
666     std::ostream& operator << (std::ostream &out, Pipe<TInput, TSpec> &src)
667     {
668         beginRead(src);
669         while (!eof(src)) {
670             out << *src << std::endl;
671             ++src;
672         }
673         endRead(src);
674         return out;
675     }
676 
677 
678     template < typename TObject, typename TSpec >
679     struct BufferHandler;
680 
681     template <typename TObject, typename TSpec>
682     struct Value<BufferHandler<TObject, TSpec> >
683     {
684         typedef Buffer<typename Value<TObject>::Type> Type;
685     };
686 
687 
688 
689     template <typename TObject, typename TSpec>
690     struct Handler;
691 
692     template <typename TObject, typename TSpec>
693     struct Value<Handler<TObject, TSpec> >:
694         public Value<TObject> {};
695 
696     // buffer-based read/write handler metafunctions
697     template < typename TInput >
698     struct BufReadHandler;
699 
700     template < typename TOutput >
701     struct BufWriteHandler;
702 
703 
704 
705     //////////////////////////////////////////////////////////////////////////////
706     // generic adapter for buffered readers/writers
707 
708     template <typename TValue, typename TSpec, typename TSize >
709     inline void resize(Buffer<TValue, TSpec> &me, TSize size);
710 
711     struct AdapterSpec;
712 
713     template <typename TBufferHandler>
714     struct Handler<TBufferHandler, AdapterSpec>
715     {
716         typedef typename Value<TBufferHandler>::Type        TBuffer;
717         typedef typename Value<TBuffer>::Type               TValue;
718         typedef typename Iterator<TBuffer, Standard>::Type  TIterator;
719 
720         TBufferHandler  handler;
721         TBuffer            buffer;
722         TIterator       cur;
723 
724         template < typename TObject >
725         Handler(TObject &_object) :
726             handler(_object), cur() {}
727 
728         inline bool begin()
729         {
730             buffer = handler.first();
731             cur = seqan::begin(buffer, Standard());
732             return true;
733         }
734 
735         inline TValue const & front() const
736         {
737             return *cur;
738         }
739 
740         inline void pop()
741         {
742             if (++cur == seqan::end(buffer, Standard()))
743             {
744                 buffer = handler.next();
745                 cur = seqan::begin(buffer, Standard());
746             }
747         }
748 
749         inline void pop(TValue &Ref_)
750         {
751             Ref_ = *cur;
752             pop();
753         }
754 
755         inline void push(TValue const & Val_)
756         {
757             if (cur == seqan::end(buffer, Standard()))
758             {
759                 buffer = handler.next();
760                 cur = seqan::begin(buffer, Standard());
761             }
762             *cur = Val_;
763             ++cur;
764         }
765 
766         inline bool eof() const
767         {
768             return length(buffer) == 0;
769         }
770 
771         inline void end()
772         {
773             handler.end();
774             resize(buffer, 0);
775         }
776 
777         inline void process()
778         {
779             handler.process();
780         }
781     };
782 
783     template <typename TBufferHandler>
784     struct Value<Handler<TBufferHandler, AdapterSpec> >:
785         public Value<typename Value<TBufferHandler>::Type> {};
786 
787     // character-based read/write handler metafunctions
788     template < typename TInput >
789     struct ReadHandler
790     {
791         typedef Handler< typename BufReadHandler<TInput> ::Type, AdapterSpec > Type;
792     };
793 
794     template < typename TOutput >
795     struct WriteHandler
796     {
797         typedef Handler< typename BufWriteHandler<TOutput> ::Type, AdapterSpec > Type;
798     };
799 
800 
801     //////////////////////////////////////////////////////////////////////////////
802     // pair incrementer
803     //
804     // used by pipes processing multiples sequences
805     // for generating pairs (seqNo, seqOffs)
806 
807     template <typename TPair, typename TLimits>
808     struct PairIncrementer_
809     {
810         typedef typename Iterator<TLimits const, Standard>::Type            TIter;
811         typedef typename RemoveConst_<typename Value<TLimits>::Type>::Type  TSize;
812         typedef typename Value<TPair, 2>::Type                              TOffset;
813 
814         TIter   it, itEnd;
815         TSize   old;
816         TOffset localEnd;
817 
818         TPair pos;
819         inline operator TPair () const
820         {
821             return pos;
822         }
823 
824         inline TPair const & operator++ ()
825         {
826             TOffset i2 = getValueI2(pos) + 1;
827             if (i2 >= localEnd)
828             {
829                 i2 = 0;
830                 localEnd = 0;
831                 while (!localEnd && (it != itEnd))
832                 {
833                     typename Value<TPair,1>::Type i1 = getValueI1(pos);
834                     assignValueI1(pos, i1 + 1);
835                     localEnd = (*it - old);
836                     // test for overflows
837                     SEQAN_ASSERT_LT_MSG(i1, getValueI1(pos), "Overflow detected. Use a bigger type for the *first* value in the SAValue pair!");
838                     SEQAN_ASSERT_EQ_MSG((TSize)localEnd, (*it - old), "Overflow detected. Use a bigger type for the *second* value in the SAValue pair!");
839                     old = *it;
840                     ++it;
841                 }
842                 if (!localEnd && it == itEnd)
843                     assignValueI1(pos, getValueI1(pos) + 1);    // set pos behind the last sequence
844             }
845             assignValueI2(pos, i2);
846             return pos;
847         }
848     };
849 
850     template <typename TPair, typename TLimits, typename TLimits2>
851     void setHost(PairIncrementer_<TPair, TLimits> &me, TLimits2 const &limits)
852     {
853         me.it = begin(limits, Standard());
854         me.itEnd = end(limits, Standard());
855         me.old = 0;
856         me.localEnd = 0;
857         me.pos = TPair(0, 0);
858         if (length(limits) > 1)
859         {
860             ++me.it;
861             ++me;
862             assignValueI1(me.pos, getValueI1(me.pos) - 1);
863         }
864     }
865 
866     template <typename TPair, typename TLimits, typename TLimits2>
867     void setHost(PairIncrementer_<TPair, TLimits> &me, TLimits2 &limits)
868     {
869         setHost(me, const_cast<TLimits2 const &>(limits));
870     }
871 //____________________________________________________________________________
872 
873     template <typename TPair, typename TLimits>
874     TPair const & value(PairIncrementer_<TPair, TLimits> const &me) {
875         return me.pos;
876     }
877 
878     template <typename TPair, typename TLimits>
879     TPair & value(PairIncrementer_<TPair, TLimits> &me) {
880         return me.pos;
881     }
882 
883 
884     //////////////////////////////////////////////////////////////////////////////
885     // pair decrementer
886     //
887     // used by pipes processing multiples sequences
888     // for generating pairs (seqNo, seqOffs)
889 
890     template <typename TPair, typename TLimits, unsigned m = 0>
891     struct PairDecrementer_
892     {
893         typedef typename Iterator<TLimits const, Standard>::Type            TIter;
894         typedef typename RemoveConst_<typename Value<TLimits>::Type>::Type  TSize;
895 
896         TIter       it, itEnd;
897         TSize       old;
898         TPair        pos;
899         unsigned    residue;
900 
901         PairDecrementer_() : it(), itEnd(), old(), pos(), residue() {}
902         PairDecrementer_(TLimits const &_limits) : it(), itEnd(), old(), pos(), residue()
903         { setHost(*this, _limits); }
904 
905         inline operator TPair () const
906         {
907             return pos;
908         }
909 
910         inline TPair const & operator-- ()
911         {
912             typename Value<TPair,2>::Type i2 = getValueI2(pos);
913             if (i2 > 1)
914             {
915                 --i2;
916                 if (residue == 0) residue = m;
917                 --residue;
918             }
919             else
920             {
921                 i2 = 0;
922                 while (!i2 && (it != itEnd))
923                 {
924                     typename Value<TPair,1>::Type i1 = getValueI1(pos);
925                     assignValueI1(pos, i1 + 1);
926                     i2 = (*it - old);
927                     // test for overflows
928                     SEQAN_ASSERT_LT_MSG(i1, getValueI1(pos), "Overflow detected. Use a bigger type for the *first* value in the SAValue pair!");
929                     SEQAN_ASSERT_EQ_MSG((TSize)i2, *it - old, "Overflow detected. Use a bigger type for the *second* value in the SAValue pair!");
930                     old = *it;
931                     ++it;
932                 }
933                 residue = i2 % m;
934             }
935             assignValueI2(pos, i2);
936             return pos;
937         }
938     };
939 
940     template <typename TPair, typename TLimits, unsigned m, typename TLimits2>
941     void setHost(PairDecrementer_<TPair, TLimits, m> &me, TLimits2 const &limits)
942     {
943         me.it = begin(limits);
944         me.itEnd = end(limits);
945         me.old = 0;
946         me.pos = TPair(0, 0);
947         if (length(limits) > 1)
948         {
949             ++me.it;
950             --me;
951             assignValueI1(me.pos, getValueI1(me.pos) - 1);
952         } else
953             me.residue = 0;
954     }
955 
956     template <typename TPair, typename TLimits, unsigned m, typename TLimits2>
957     void setHost(PairDecrementer_<TPair, TLimits, m> &me, TLimits2 &limits)
958     {
959         setHost(me, const_cast<TLimits const &>(limits));
960     }
961 //____________________________________________________________________________
962 
963     template <typename TPair, typename TLimits>
964     struct PairDecrementer_<TPair, TLimits, 0>
965     {
966         typedef typename Iterator<TLimits const, Standard>::Type            TIter;
967         typedef typename RemoveConst_<typename Value<TLimits>::Type>::Type  TSize;
968 
969         TIter       it, itEnd;
970         TSize       old;
971         TPair        pos;
972 
973         PairDecrementer_() {}
974         PairDecrementer_(TLimits const &_limits) { setHost(*this, _limits); }
975 
976         inline operator TPair () const {
977             return pos;
978         }
979 
980         inline TPair const & operator-- ()
981         {
982             typename Value<TPair,2>::Type i2 = getValueI2(pos);
983             if (i2 > 1)
984                 --i2;
985             else
986             {
987                 i2 = 0;
988                 while (!i2 && (it != itEnd))
989                 {
990                     typename Value<TPair,1>::Type i1 = getValueI1(pos);
991                     assignValueI1(pos, i1 + 1);
992                     i2 = (*it - old);
993                     // test for overflows
994                     SEQAN_ASSERT_LT_MSG(i1, getValueI1(pos), "Overflow detected. Use a bigger type for the *first* value in the SAValue pair!");
995                     SEQAN_ASSERT_EQ_MSG((TSize)i2, *it - old, "Overflow detected. Use a bigger type for the *second* value in the SAValue pair!");
996                     old = *it;
997                     ++it;
998                 }
999             }
1000             assignValueI2(pos, i2);
1001             return pos;
1002         }
1003     };
1004 
1005     template <typename TPair, typename TLimits, typename TLimits2>
1006     void setHost(PairDecrementer_<TPair, TLimits, 0> &me, TLimits2 const &limits) {
1007         me.it = begin(limits);
1008         me.itEnd = end(limits);
1009         me.old = 0;
1010         assignValueI1(me.pos, 0);
1011         assignValueI2(me.pos, 0);
1012         if (length(limits) > 1) {
1013             ++me.it;
1014             --me;
1015             assignValueI1(me.pos, getValueI1(me.pos) - 1);
1016         }
1017     }
1018 
1019     template <typename TPair, typename TLimits, typename TLimits2>
1020     void setHost(PairDecrementer_<TPair, TLimits, 0> &me, TLimits2 &limits)
1021     {
1022         setHost(me, const_cast<TLimits const &>(limits));
1023     }
1024 //____________________________________________________________________________
1025 
1026     template <typename TPair, typename TLimits, unsigned m>
1027     TPair const & value(PairDecrementer_<TPair, TLimits, m> const &me) {
1028         return me.pos;
1029     }
1030 
1031     template <typename TPair, typename TLimits, unsigned m>
1032     TPair & value(PairDecrementer_<TPair, TLimits, m> &me) {
1033         return me.pos;
1034     }
1035 
1036 }
1037 
1038 #endif
1039