SeqAn3  3.0.1
The Modern C++ library for sequence analysis.
iterator.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2020, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2020, Knut Reinert & MPI für molekulare Genetik
4 // This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5 // shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6 // -----------------------------------------------------------------------------------------------------
7 
13 #pragma once
14 
15 #include <iterator>
16 
17 #ifndef __cpp_lib_ranges
18 #include <range/v3/iterator/stream_iterators.hpp>
19 #endif // __cpp_lib_ranges
20 
21 #include <seqan3/core/platform.hpp>
22 #include <seqan3/std/ranges>
23 
24 namespace seqan3::detail
25 {
26 // ============================================================================
27 // fast_istreambuf_iterator
28 // ============================================================================
29 
40 template <typename char_t, typename traits_t = std::char_traits<char_t>>
41 struct stream_buffer_exposer : public std::basic_streambuf<char_t, traits_t>
42 {
45 
46  // Expose protected members:
47  using base_t::eback;
48  using base_t::gptr;
49  using base_t::egptr;
50  using base_t::gbump;
51  using base_t::underflow;
52 
53  using base_t::pbase;
54  using base_t::pptr;
55  using base_t::epptr;
56  using base_t::pbump;
57  using base_t::overflow;
58 };
59 
72 template <typename char_t, typename traits_t = std::char_traits<char_t>>
73 class fast_istreambuf_iterator
74 {
75 private:
77  stream_buffer_exposer<char_t, traits_t> * stream_buf = nullptr;
78 
79 public:
83  using difference_type = ptrdiff_t;
84  using value_type = char_t;
85  using reference = char_t;
86  using pointer = void;
87  using iterator_category = std::input_iterator_tag;
88 
93  fast_istreambuf_iterator() noexcept = default;
94  fast_istreambuf_iterator(fast_istreambuf_iterator const &) noexcept = default;
95  fast_istreambuf_iterator(fast_istreambuf_iterator &&) noexcept = default;
96  fast_istreambuf_iterator & operator=(fast_istreambuf_iterator const &) noexcept = default;
97  fast_istreambuf_iterator & operator=(fast_istreambuf_iterator &&) noexcept = default;
98  ~fast_istreambuf_iterator() noexcept = default;
99 
101  explicit fast_istreambuf_iterator(std::basic_streambuf<char_t, traits_t> & ibuf) :
102  stream_buf{reinterpret_cast<stream_buffer_exposer<char_t, traits_t> *>(&ibuf)}
103  {
104  assert(stream_buf != nullptr);
105  stream_buf->underflow(); // ensure the stream buffer has content on construction
106  }
108 
112  fast_istreambuf_iterator & operator++()
114  {
115  assert(stream_buf != nullptr);
116  if ((stream_buf->gptr() + 1) == stream_buf->egptr())
117  stream_buf->snextc(); // move right, then underflow()
118  else
119  stream_buf->gbump(1);
120  return *this;
121  }
122 
124  void operator++(int)
125  {
126  ++(*this);
127  }
129 
131  reference operator*() const
132  {
133  assert(stream_buf != nullptr);
134  return *stream_buf->gptr();
135  }
136 
141  friend bool operator==(fast_istreambuf_iterator const & lhs, std::ranges::default_sentinel_t const &) noexcept
143  {
144  assert(lhs.stream_buf != nullptr);
145  // compare size of remaining buffer; since ++ always resizes if possible, safe to compare pointers here
146  return (lhs.stream_buf->gptr() == lhs.stream_buf->egptr());
147  }
148 
150  friend bool operator!=(fast_istreambuf_iterator const & lhs, std::ranges::default_sentinel_t const &) noexcept
151  {
152  return !(lhs == std::ranges::default_sentinel);
153  }
154 
156  friend bool operator==(std::ranges::default_sentinel_t const &, fast_istreambuf_iterator const & rhs) noexcept
157  {
158  return rhs == std::ranges::default_sentinel;
159  }
160 
162  friend bool operator!=(std::ranges::default_sentinel_t const &, fast_istreambuf_iterator const & rhs) noexcept
163  {
164  return !(rhs == std::ranges::default_sentinel);
165  }
167 };
168 
169 } // namespace seqan3::detail
170 
171 namespace seqan3
172 {
173 
178 #ifdef __cpp_lib_ranges
179 
184 using SEQAN3_DOXYGEN_ONLY(ostream_iterator =) ::std::ostream_iterator;
185 
190 using SEQAN3_DOXYGEN_ONLY(ostreambuf_iterator =) ::std::ostreambuf_iterator;
191 
192 #else
193 
198 using SEQAN3_DOXYGEN_ONLY(ostream_iterator =) ::ranges::ostream_iterator;
199 
204 using SEQAN3_DOXYGEN_ONLY(ostreambuf_iterator =) ::ranges::ostreambuf_iterator;
205 
206 #endif // __cpp_lib_ranges
207 } // namespace seqan3
std::rel_ops::operator!=
T operator!=(T... args)
std::basic_streambuf< char_t, traits_t >::pbase
T pbase(T... args)
seqan3::ostream_iterator
::ranges::ostream_iterator ostream_iterator
Alias for ranges::ostream_iterator. Writes successive elements onto the output stream from which it w...
Definition: iterator.hpp:198
std::input_iterator_tag
std::basic_streambuf
std::basic_streambuf< char_t, traits_t >::pbump
T pbump(T... args)
std::basic_streambuf< char_t, traits_t >::eback
T eback(T... args)
std::basic_streambuf< char_t, traits_t >::underflow
T underflow(T... args)
std::basic_streambuf< char_t, traits_t >::gbump
T gbump(T... args)
seqan3::ostreambuf_iterator
::ranges::ostreambuf_iterator ostreambuf_iterator
Alias for ranges::ostreambuf_iterator. Writes successive characters onto the output stream from which...
Definition: iterator.hpp:204
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:36
std::basic_streambuf< char_t, traits_t >::overflow
T overflow(T... args)
ranges
Adaptations of concepts from the Ranges TS.
platform.hpp
Provides platform and dependency checks.
std
SeqAn specific customisations in the standard namespace.