Browse code

seqan header files

aguang authored on 15/02/2018 18:04:57
Showing1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,768 @@
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
+// Author: Enrico Siragusa <enrico.siragusa@fu-berlin.de>
34
+// ==========================================================================
35
+// Our own implementation of a streambuf_iterator. We could not use the STL's
36
+// iterator as we need to have access to the underlying streambuf which is a
37
+// private member of the STL iterator.
38
+// ==========================================================================
39
+// TODO(esiragusa): tests
40
+
41
+#ifndef SEQAN_INCLUDE_SEQAN_STREAM_ITER_STREAM_H_
42
+#define SEQAN_INCLUDE_SEQAN_STREAM_ITER_STREAM_H_
43
+
44
+namespace seqan {
45
+
46
+// ============================================================================
47
+// Tags
48
+// ============================================================================
49
+
50
+template <typename TDirection>
51
+struct StreamIterator {};
52
+
53
+// ============================================================================
54
+// Classes
55
+// ============================================================================
56
+
57
+// ----------------------------------------------------------------------------
58
+// Class StreamBuffer
59
+// ----------------------------------------------------------------------------
60
+
61
+/*!
62
+ * @class StreamBuffer
63
+ * @headerfile <seqan/stream.h>
64
+ * @brief Reinterprets the std::basic_streambuf to grant access to protected member functions.
65
+ *
66
+ * @signature template <typename TValue[, typenam TTraits]>
67
+ *            class StreamBuffer : public std::basic_streambuf<TValue, TTraits>;
68
+ *
69
+ * @tparam TValue  The value type of the stream buffer.
70
+ * @tparam TTraits The traits to use, defaults to <tt>std::char_traits&lt;TValue&gt;</tt>.
71
+ */
72
+// TODO(holtgrew): Add documentation for member functions.
73
+
74
+ // Unfortunately some of the most useful members of basic_streambuf are
75
+ // protected, so we define a subclass to cast and access them
76
+template <typename TValue, typename TTraits_ = std::char_traits<TValue>>
77
+struct StreamBuffer : public std::basic_streambuf<TValue, TTraits_>
78
+{
79
+    using TTraits      = TTraits_;
80
+    using TBasicStream = std::basic_streambuf<TValue, TTraits_>;
81
+
82
+    using TBasicStream::eback;
83
+    using TBasicStream::gptr;
84
+    using TBasicStream::egptr;
85
+    using TBasicStream::gbump;
86
+    using TBasicStream::underflow;
87
+
88
+    using TBasicStream::pbase;
89
+    using TBasicStream::pptr;
90
+    using TBasicStream::epptr;
91
+    using TBasicStream::pbump;
92
+    using TBasicStream::overflow;
93
+};
94
+
95
+// NOTE(rrahn): This is a wrapper for the StreamBuffer class.
96
+// Since we usually work with std::basic_iostreams and their derivatives, we cannot simply cast a pointer to
97
+// std::basic_filebuf to StreamBuffer to expose it's protected member functions.
98
+// To do so, we only use the StreamBuffer to inherit from basic_streambuf (the base class of all buffer implementations.)
99
+// and only expose the protected member functions as public functions. We then store the original basic_streambuf
100
+// in this wrapper class and whenever access to the protected members is required we use a reinterpret_cast to convert
101
+// basic_streambuf* into the public StreamBuffer*. The reinterpret_cast has zero overhead.
102
+// This fixes an undetected error reported w/ the sanitizer option of gcc (https://github.com/seqan/seqan/issues/2104).
103
+template <typename TValue, typename TTraits_ = std::char_traits<TValue>>
104
+class StreamBufferWrapper
105
+{
106
+public:
107
+
108
+    typedef std::basic_streambuf<TValue, TTraits_> TBasicStreamBuffer;
109
+    typedef StreamBuffer<TValue, TTraits_>         TPubStreamBuffer_;
110
+    typedef typename TPubStreamBuffer_::TTraits    TTraits;
111
+
112
+    TBasicStreamBuffer * streamBuf{nullptr};
113
+
114
+    StreamBufferWrapper() = default;
115
+
116
+    explicit StreamBufferWrapper(TBasicStreamBuffer * _basicStreamBuf) : streamBuf(_basicStreamBuf)
117
+    {}
118
+
119
+    size_t chunkSize(Input)
120
+    {
121
+        return baseBuf()->egptr() - baseBuf()->gptr();
122
+    }
123
+
124
+    size_t chunkSize(Output)
125
+    {
126
+        return baseBuf()->epptr() - baseBuf()->pptr();
127
+    }
128
+
129
+    template <typename TOffset>
130
+    void advanceChunk(TOffset ofs, Input)
131
+    {
132
+        baseBuf()->gbump(ofs);
133
+    }
134
+
135
+    template <typename TOffset>
136
+    void advanceChunk(TOffset ofs, Output)
137
+    {
138
+        baseBuf()->pbump(ofs);
139
+    }
140
+
141
+    void reserveChunk(Input)
142
+    {
143
+        if (baseBuf()->gptr() == baseBuf()->egptr())
144
+            baseBuf()->underflow();
145
+    }
146
+
147
+    void reserveChunk(Output)
148
+    {
149
+        if (baseBuf()->pptr() == baseBuf()->epptr())
150
+            baseBuf()->overflow(EOF);
151
+    }
152
+
153
+    template <typename TOffset>
154
+    typename std::streampos
155
+    seekoff(TOffset ofs, std::ios_base::seekdir way, std::ios_base::openmode which)
156
+    {
157
+        return streamBuf->pubseekoff(ofs, way, which);
158
+    }
159
+
160
+    template <typename TOffset, typename TDirection>
161
+    void goFurther(TOffset ofs, TDirection dir)
162
+    {
163
+        size_t left = chunkSize(dir);
164
+        if (SEQAN_LIKELY((size_t)ofs <= left))
165
+        {
166
+            advanceChunk(ofs, dir);
167
+            return;
168
+        }
169
+
170
+        while (true)
171
+        {
172
+            size_t adv = std::min((size_t)ofs, left);
173
+            advanceChunk(adv, dir);
174
+            ofs -= adv;
175
+            if (ofs == 0)
176
+                return;
177
+
178
+            SEQAN_IF_CONSTEXPR (IsSameType<TDirection, Input>::VALUE)
179
+                baseBuf()->underflow();
180
+            else
181
+                baseBuf()->overflow();
182
+            left = chunkSize(dir);
183
+
184
+            if (SEQAN_UNLIKELY(left == 0))
185
+            {
186
+                // if chunking isn't available try to seek
187
+                typename TTraits::pos_type res = seekoff(ofs,
188
+                                                         std::ios_base::cur,
189
+                                                         (IsSameType<TDirection, Input>::VALUE)? std::ios_base::in: std::ios_base::out);
190
+
191
+                // if seek doesn't work manually skip characters (when reading)
192
+                if (res == typename TTraits::pos_type(typename TTraits::off_type(-1)))
193
+                {
194
+                    SEQAN_IF_CONSTEXPR (IsSameType<TDirection, Input>::VALUE)
195
+                    {
196
+                        for (; ofs != 0; --ofs)
197
+                            baseBuf()->sbumpc();
198
+                    }
199
+                    SEQAN_IF_CONSTEXPR (IsSameType<TDirection, Output>::VALUE)
200
+                    {
201
+                        for (; ofs != 0; --ofs)
202
+                            baseBuf()->sputc('\0');
203
+                    }
204
+                }
205
+                return;
206
+            }
207
+        }
208
+    }
209
+
210
+    TPubStreamBuffer_* baseBuf() const
211
+    {
212
+        return reinterpret_cast<TPubStreamBuffer_ *>(streamBuf);
213
+    }
214
+};
215
+
216
+// ----------------------------------------------------------------------------
217
+// Class StreamIterator
218
+// ----------------------------------------------------------------------------
219
+
220
+/*!
221
+ * @class StreamIterator
222
+ * @extends Iter
223
+ * @brief Abstract base class for input and output stream iterators.
224
+ *
225
+ * @signature template <typename TStream, typename TDirection>
226
+ *            class Iter<TStream, StreamIterator<TDirection> >;
227
+ *
228
+ * @tparam TStream    The @link StreamConcept @endlink to iterate over.
229
+ * @tparam TDirection The iterator direction, one of the @link DirectionTags @endlink.
230
+ */
231
+
232
+// ----------------------------------------------------------------------------
233
+// Class Input StreamIterator
234
+// ----------------------------------------------------------------------------
235
+
236
+/*!
237
+ * @class InputStreamIterator Input StreamIterator
238
+ * @extends StreamIterator
239
+ * @brief @link Iter @endlink specialiazion for reading from @link StreamConcept streams @endlink.
240
+ *
241
+ * @signature template <typename TStream>
242
+ *            class Iter<TStream, StreamIterator<Input> >;
243
+ *
244
+ * @tparam TStream    The @link StreamConcept @endlink to iterate over.
245
+ */
246
+
247
+template <typename TStream>
248
+class Iter<TStream, StreamIterator<Input> >
249
+{
250
+public:
251
+    typedef typename Value<TStream>::Type                    TValue;
252
+    typedef std::basic_istream<TValue>                       TIStream;
253
+    typedef std::basic_streambuf<TValue>                     TBasicBuffer;
254
+    typedef StreamBufferWrapper<TValue>                      TStreamBufferWrapper;
255
+    typedef typename TStreamBufferWrapper::TPubStreamBuffer_ TStreamBuffer;
256
+
257
+    TStreamBufferWrapper streamBufWrapper{nullptr};
258
+
259
+    /*!
260
+     * @fn InputStreamIterator::Iter
261
+     * @brief The constructors.
262
+     *
263
+     * @signature Iter::Iter();
264
+     * @signature Iter::Iter(stream);
265
+     * @signature Iter::Iter(streamBuffer);
266
+     *
267
+     * @param[in] stream    The <tt>TStream</tt> to read from.
268
+     * @param[in] streamBuf A @link StreamBuffer @endlink to read from.
269
+     *
270
+     * Allows default construction, construction from stream, as well as from a @link StreamBuffer @endlink.
271
+     */
272
+    Iter() = default;
273
+
274
+    Iter(TIStream & stream) : streamBufWrapper(stream.rdbuf())
275
+    {
276
+        // printf("streamBuf: %p\n", streamBuf);
277
+        stream.exceptions(std::ios_base::badbit);
278
+    }
279
+
280
+    Iter(TBasicBuffer * buf) : streamBufWrapper(buf)
281
+    {}
282
+};
283
+
284
+// ----------------------------------------------------------------------------
285
+// Class StreamIterator
286
+// ----------------------------------------------------------------------------
287
+
288
+/*!
289
+ * @class OutputStreamIterator Output StreamIterator
290
+ * @extends StreamIterator
291
+ * @brief @link Iter @endlink specialiazion for writing to @link StreamConcept streams @endlink.
292
+ *
293
+ * @signature template <typename TStream>
294
+ *            class Iter<TStream, StreamIterator<Output> >;
295
+ *
296
+ * @tparam TStream    The @link StreamConcept @endlink to iterate over.
297
+ */
298
+template <typename TStream>
299
+class Iter<TStream, StreamIterator<Output> >
300
+{
301
+public:
302
+    typedef typename Value<TStream>::Type                    TValue;
303
+    typedef std::basic_ostream<TValue>                       TOStream;
304
+    typedef std::basic_streambuf<TValue>                     TBasicBuffer;
305
+    typedef StreamBufferWrapper<TValue>                      TStreamBufferWrapper;
306
+    typedef typename TStreamBufferWrapper::TPubStreamBuffer_ TStreamBuffer;
307
+
308
+    TStreamBufferWrapper streamBufWrapper{nullptr};
309
+
310
+    /*!
311
+     * @fn Iter::Iter
312
+     * @brief Constructor.
313
+     *
314
+     * @signature Iter::Iter()
315
+     * @signature Iter::Iter(stream)
316
+     * @signature Iter::Iter(streamBuf)
317
+     *
318
+     * @param[in] stream    The <tt>TStream</tt> to write to.
319
+     * @param[in] streamBuf A @link StreamBuffer @endlink to write to.
320
+     *
321
+     * Allows default construction, construction from stream, as well as from a @link StreamBuffer @endlink.
322
+     */
323
+    Iter() = default;
324
+
325
+    Iter(TOStream & stream) : streamBufWrapper(stream.rdbuf())
326
+    {
327
+        stream.exceptions(std::ios_base::badbit);
328
+    }
329
+
330
+    Iter(TBasicBuffer * buf) : streamBufWrapper(buf)
331
+    {}
332
+
333
+    template <typename TValue2>
334
+    TValue2 & operator=(TValue2 &val)
335
+    {
336
+        setValue(*this, val);
337
+        return val;
338
+    }
339
+
340
+    template <typename TValue2>
341
+    TValue2 const & operator=(TValue2 const &val)
342
+    {
343
+        setValue(*this, val);
344
+        return val;
345
+    }
346
+};
347
+
348
+
349
+// ============================================================================
350
+// Metafunctions
351
+// ============================================================================
352
+
353
+// ----------------------------------------------------------------------------
354
+// Metafunction Chunk
355
+// ----------------------------------------------------------------------------
356
+
357
+/*!
358
+ * @mfn StreamBuffer#Chunk
359
+ * @brief Return chunk type for StreamBuffer
360
+ *
361
+ * @signature Chunk<TStreamBuffer>::Type;
362
+ *
363
+ * @tparam TStreamBuffer The StreamBuffer to query for its chunk type.
364
+ * @return Type          The chunk type of the stream buffer.
365
+ */
366
+
367
+template <typename TValue, typename TTraits>
368
+struct Chunk<StreamBuffer<TValue, TTraits> >
369
+{
370
+    typedef Range<TValue*> Type;
371
+};
372
+
373
+template <typename TStream, typename TDirection>
374
+struct Chunk<Iter<TStream, StreamIterator<Tag<TDirection> > > >:
375
+    Chunk<typename Iter<TStream, StreamIterator<Tag<TDirection> > >::TStreamBuffer> {};
376
+
377
+// ----------------------------------------------------------------------------
378
+// Metafunction Reference
379
+// ----------------------------------------------------------------------------
380
+
381
+/*!
382
+ * @mfn StreamBuffer#Reference
383
+ * @brief Return reference for StreamBuffer.
384
+ *
385
+ * @signature Reference<TStreamBuffer>::Type;
386
+ *
387
+ * @tparam TStreamBuffer The StreamBuffer to query for its reference type.
388
+ * @return Type          The reference type of the stream buffer.
389
+ */
390
+
391
+template <typename TStream>
392
+struct Reference<Iter<TStream, StreamIterator<Input> > >:
393
+    Value<Iter<TStream, StreamIterator<Input> > > {};
394
+
395
+template <typename TStream>
396
+struct Reference<Iter<TStream, StreamIterator<Input> > const>:
397
+    Value<Iter<TStream, StreamIterator<Input> > > {};
398
+
399
+template <typename TStream>
400
+struct Reference<Iter<TStream, StreamIterator<Output> > >
401
+{
402
+    typedef Iter<TStream, StreamIterator<Output> > Type;
403
+};
404
+
405
+// ----------------------------------------------------------------------------
406
+// Metafunction GetValue
407
+// ----------------------------------------------------------------------------
408
+
409
+/*!
410
+ * @mfn StreamBuffer#GetValue
411
+ * @brief Return get value for StreamBuffer.
412
+ *
413
+ * @signature GetValue<TStreamBuffer>::Type;
414
+ *
415
+ * @tparam TStreamBuffer The StreamBuffer to query for its get value type.
416
+ * @return Type          The get value type of the stream buffer.
417
+ */
418
+
419
+template <typename TStream>
420
+struct GetValue<Iter<TStream, StreamIterator<Input> > >:
421
+    Reference<Iter<TStream, StreamIterator<Input> > const> {};
422
+
423
+// ----------------------------------------------------------------------------
424
+// Metafunction Position
425
+// ----------------------------------------------------------------------------
426
+
427
+/*!
428
+ * @mfn StreamBuffer#Position
429
+ * @brief Return position for StreamBuffer.
430
+ *
431
+ * @signature Position<TStreamBuffer>::Type;
432
+ *
433
+ * @tparam TStreamBuffer The StreamBuffer to query for its position type.
434
+ * @return Type          The position type of the stream buffer.
435
+ */
436
+
437
+template <typename TStream, typename TDirection>
438
+struct Position<Iter<TStream, StreamIterator<TDirection> > > : Position<TStream> {};
439
+
440
+// ----------------------------------------------------------------------------
441
+// Metafunction Difference
442
+// ----------------------------------------------------------------------------
443
+
444
+/*!
445
+ * @mfn StreamBuffer#Difference
446
+ * @brief Return difference for StreamBuffer.
447
+ *
448
+ * @signature Difference<TStreamBuffer>::Type;
449
+ *
450
+ * @tparam TStreamBuffer The StreamBuffer to query for its difference type.
451
+ * @return Type          The difference type of the stream buffer.
452
+ */
453
+
454
+template <typename TStream, typename TDirection>
455
+struct Difference<Iter<TStream, StreamIterator<TDirection> > > : Difference<TStream> {};
456
+
457
+// ----------------------------------------------------------------------------
458
+// Metafunction Size
459
+// ----------------------------------------------------------------------------
460
+
461
+/*!
462
+ * @mfn StreamBuffer#Size
463
+ * @brief Return size for StreamBuffer.
464
+ *
465
+ * @signature Size<TStreamBuffer>::Type;
466
+ *
467
+ * @tparam TStreamBuffer The StreamBuffer to query for its size type.
468
+ * @return Type          The size type of the stream buffer.
469
+ */
470
+
471
+template <typename TStream, typename TDirection>
472
+struct Size<Iter<TStream, StreamIterator<TDirection> > > : Size<TStream> {};
473
+
474
+// ============================================================================
475
+// Functions
476
+// ============================================================================
477
+
478
+// ----------------------------------------------------------------------------
479
+// Function directionIterator()
480
+// ----------------------------------------------------------------------------
481
+
482
+/*!
483
+ * @fn StreamConcept#directionIterator
484
+ * @brief Returns direction iterator for Stream.
485
+ *
486
+ * @signature TDirIter directionIterator(stream, dirTag);
487
+ *
488
+ * @param[in] stream The @link StreamConcept @endlink object to compute iterator for.
489
+ * @param[in] dirTag Direction tag, one of the @link DirectionTags @endlink.
490
+ */
491
+
492
+template <typename TStream, typename TDirection>
493
+inline SEQAN_FUNC_ENABLE_IF(Is<StreamConcept<TStream> >, Iter<TStream, StreamIterator<TDirection> >)
494
+directionIterator(TStream &stream, TDirection const &)
495
+{
496
+    return Iter<TStream, StreamIterator<TDirection> >(stream);
497
+}
498
+
499
+/*!
500
+ * @fn ContainerConcept#directionIterator
501
+ * @brief Returns direction iterator for a container.
502
+ *
503
+ * @signature TDirIter directionIterator(streamBuf, dirTag);
504
+ *
505
+ * @param[in] streamBuf The @link ContainerConcept container @endlink object to compute iterator for.
506
+ * @param[in] dirTag    Direction tag, one of the @link DirectionTags @endlink.
507
+ *
508
+ * @return TDirIter The resulting @link ContainerConcept#DirectionIterator @endlink.
509
+ */
510
+
511
+template <typename TContainer, typename TDirection>
512
+inline SEQAN_FUNC_DISABLE_IF(Is<StreamConcept<TContainer> >, typename Iterator<TContainer, Rooted>::Type)
513
+directionIterator(TContainer &cont, TDirection const &)
514
+{
515
+    return begin(cont, Rooted());
516
+}
517
+
518
+// ----------------------------------------------------------------------------
519
+// Function reserveChunk()
520
+// ----------------------------------------------------------------------------
521
+
522
+/*!
523
+ * @fn StreamIterator#reserveChunk
524
+ * @brief Reserve a chunk in the host of the StreamIterator
525
+ *
526
+ * @signature void reserveChunk(iter, len, dirTag);
527
+ *
528
+ * @param[in] iter   The @link StreamIterator @endlink object to reserve chunks for.
529
+ * @param[in] len    The length of the chunk to reserve.
530
+ * @param[in] dirTag Direction tag, one of @link DirectionTags#Input Input @endlink and @link
531
+ *                   DirectionTags#Input Output @endlink .
532
+ */
533
+
534
+template <typename TStream, typename TDirection, typename TSize>
535
+inline void reserveChunk(Iter<TStream, StreamIterator<TDirection> > &iter, TSize, Input dir)
536
+{
537
+    iter.streamBufWrapper.reserveChunk(dir);
538
+}
539
+
540
+template <typename TStream, typename TDirection, typename TSize>
541
+inline void reserveChunk(Iter<TStream, StreamIterator<TDirection> > &iter, TSize, Output dir)
542
+{
543
+    iter.streamBufWrapper.reserveChunk(dir);
544
+}
545
+
546
+// ----------------------------------------------------------------------------
547
+// Function advanceChunk()
548
+// ----------------------------------------------------------------------------
549
+
550
+// TODO(holtgrew): Documentation missing below here.
551
+
552
+template <typename TStream, typename TDirection, typename TSize>
553
+inline void advanceChunk(Iter<TStream, StreamIterator<TDirection> > &iter, TSize size)
554
+{
555
+    iter.streamBufWrapper.advanceChunk(size, TDirection());
556
+}
557
+
558
+// ----------------------------------------------------------------------------
559
+// Function getChunk()
560
+// ----------------------------------------------------------------------------
561
+
562
+// StreamBuffer
563
+template <typename TChunk, typename TValue, typename TTraits>
564
+inline void
565
+getChunk(TChunk &result, StreamBuffer<TValue, TTraits> &buf, Input)
566
+{
567
+    return assignRange(result, buf.gptr(), buf.egptr());
568
+}
569
+
570
+template <typename TChunk, typename TValue, typename TTraits>
571
+inline void
572
+getChunk(TChunk &result, StreamBuffer<TValue, TTraits> &buf, Output)
573
+{
574
+    return assignRange(result, buf.pptr(), buf.epptr());
575
+}
576
+
577
+// StreamIterator
578
+template <typename TChunk, typename TStream, typename TDirection>
579
+inline void
580
+getChunk(TChunk &result, Iter<TStream, StreamIterator<Tag<TDirection> > > &iter, Tag<TDirection>)
581
+{
582
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
583
+    getChunk(result, *iter.streamBufWrapper.baseBuf(), Tag<TDirection>());
584
+}
585
+
586
+// ----------------------------------------------------------------------------
587
+// Function value() - Input
588
+// ----------------------------------------------------------------------------
589
+
590
+template <typename TStream>
591
+inline typename Reference<Iter<TStream, StreamIterator<Input> > >::Type
592
+value(Iter<TStream, StreamIterator<Input> > &iter)
593
+{
594
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
595
+    return iter.streamBufWrapper.baseBuf()->sgetc();
596
+}
597
+template <typename TStream>
598
+inline typename Reference<Iter<TStream, StreamIterator<Input> > const>::Type
599
+value(Iter<TStream, StreamIterator<Input> > const &iter)
600
+{
601
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
602
+    return iter.streamBufWrapper.baseBuf()->sgetc();
603
+}
604
+
605
+// ----------------------------------------------------------------------------
606
+// Function value() - Ouput
607
+// ----------------------------------------------------------------------------
608
+
609
+template <typename TStream>
610
+inline Iter<TStream, StreamIterator<Output> > &
611
+value(Iter<TStream, StreamIterator<Output> > & iter)
612
+{
613
+    return iter;
614
+}
615
+template <typename TStream>
616
+inline Iter<TStream, StreamIterator<Output> > const &
617
+value(Iter<TStream, StreamIterator<Output> > const & iter)
618
+{
619
+    return iter;
620
+}
621
+
622
+// ----------------------------------------------------------------------------
623
+// Function setValue()
624
+// ----------------------------------------------------------------------------
625
+
626
+template <typename TStream, typename TValue>
627
+inline void
628
+setValue(Iter<TStream, StreamIterator<Output> > & iter, TValue const &val)
629
+{
630
+    return setValue(const_cast<Iter<TStream, StreamIterator<Output> > const &>(iter), val);
631
+}
632
+
633
+template <typename TStream, typename TValue>
634
+inline void
635
+setValue(Iter<TStream, StreamIterator<Output> > const & iter, TValue const &val)
636
+{
637
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
638
+    iter.streamBufWrapper.baseBuf()->sputc((typename Value<Iter<TStream, StreamIterator<Output> > >::Type)val);
639
+}
640
+
641
+// ----------------------------------------------------------------------------
642
+// Function writeValue()
643
+// ----------------------------------------------------------------------------
644
+
645
+// streams
646
+template <typename TContainer, typename TValue>
647
+inline void writeValue(Iter<TContainer, StreamIterator<Output> > &iter, TValue val)
648
+{
649
+    setValue(iter, val);
650
+    //goNext(iter);     // implicitly done by setValue above
651
+}
652
+
653
+// ----------------------------------------------------------------------------
654
+// Function goNext()
655
+// ----------------------------------------------------------------------------
656
+
657
+template <typename TStream>
658
+inline void
659
+goNext(Iter<TStream, StreamIterator<Input> > & iter)
660
+{
661
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
662
+    iter.streamBufWrapper.baseBuf()->sbumpc();
663
+}
664
+
665
+template <typename TStream>
666
+inline void
667
+goNext(Iter<TStream, StreamIterator<Output> > &)
668
+{
669
+    // We do nothing here, as the stream is advanced by sputc whenever you assign
670
+    // a value to the iterator with *iter= or setValue
671
+}
672
+
673
+// we intentionally don't return an iterator here, as the copied iterator wouldn't
674
+// point to the position before the increment.
675
+template <typename TContainer, typename TSpec>
676
+inline void
677
+operator++(Iter<TContainer, StreamIterator<Input> > & iter, int)
678
+{
679
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
680
+    iter.streamBufWrapper.baseBuf()->sbumpc();
681
+}
682
+
683
+// ----------------------------------------------------------------------------
684
+// Function goFurther()
685
+// ----------------------------------------------------------------------------
686
+
687
+template <typename TStream, typename TOffset, typename TDirection>
688
+inline void
689
+goFurther(Iter<TStream, StreamIterator<TDirection> > &iter, TOffset ofs)
690
+{
691
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
692
+    iter.streamBufWrapper.goFurther(ofs, TDirection());
693
+}
694
+
695
+// ----------------------------------------------------------------------------
696
+// Function position()
697
+// ----------------------------------------------------------------------------
698
+
699
+template <typename TStream, typename TDirection>
700
+inline typename Position<Iter<TStream, StreamIterator<TDirection> > const>::Type
701
+position(Iter<TStream, StreamIterator<TDirection> > const & iter)
702
+{
703
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
704
+    return iter.streamBufWrapper.baseBuf()->pubseekoff(0, std::ios_base::cur,
705
+                                      (IsSameType<TDirection, Input>::VALUE)? std::ios_base::in: std::ios_base::out);
706
+}
707
+
708
+// ----------------------------------------------------------------------------
709
+// Function setPosition()
710
+// ----------------------------------------------------------------------------
711
+
712
+template <typename TStream, typename TDirection, typename TPosition>
713
+inline void
714
+setPosition(Iter<TStream, StreamIterator<TDirection> > const & iter, TPosition pos)
715
+{
716
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
717
+    iter.streamBufWrapper.baseBuf()->pubseekpos(pos, (IsSameType<TDirection, Input>::VALUE)? std::ios_base::in: std::ios_base::out);
718
+}
719
+
720
+// ----------------------------------------------------------------------------
721
+// Function atEnd()
722
+// ----------------------------------------------------------------------------
723
+
724
+template <typename TStream>
725
+inline bool
726
+atEnd(Iter<TStream, StreamIterator<Input> > const & iter)
727
+{
728
+    typedef typename Value<Iter<TStream, StreamIterator<Input> > >::Type TValue;
729
+    typedef StreamBuffer<TValue> TStreamBuffer;
730
+
731
+    if (SEQAN_UNLIKELY(iter.streamBufWrapper.baseBuf() == nullptr))
732
+    {
733
+        return true;
734
+    }
735
+    else
736
+    {
737
+        TStreamBuffer * const buf = iter.streamBufWrapper.baseBuf();
738
+        if (SEQAN_LIKELY(buf->gptr() < buf->egptr()))
739
+            return false;
740
+        else
741
+            return TStreamBuffer::TTraits::eq_int_type(buf->sgetc(), TStreamBuffer::TTraits::eof());
742
+    }
743
+}
744
+
745
+template <typename TStream>
746
+inline bool
747
+atEnd(Iter<TStream, StreamIterator<Output> > const & iter)
748
+{
749
+    typedef typename Value<Iter<TStream, StreamIterator<Input> > >::Type TValue;
750
+    typedef StreamBuffer<TValue> TStreamBuffer;
751
+
752
+    if (SEQAN_UNLIKELY(iter.streamBufWrapper.baseBuf() == nullptr))
753
+    {
754
+        return true;
755
+    }
756
+    else
757
+    {
758
+        TStreamBuffer * const buf = iter.streamBufWrapper.baseBuf();
759
+        if (SEQAN_LIKELY(buf->pptr() < buf->epptr()))
760
+            return false;
761
+        else
762
+            return TStreamBuffer::TTraits::eq_int_type(buf->overflow(), TStreamBuffer::TTraits::eof());
763
+    }
764
+}
765
+
766
+}  // namespace seqan
767
+
768
+#endif  // #ifndef SEQAN_INCLUDE_SEQAN_STREAM_ITER_STREAM_H_