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 
47  // Expose protected members:
48  using base_t::eback;
49  using base_t::gptr;
50  using base_t::egptr;
51  using base_t::gbump;
52  using base_t::underflow;
53 
54  using base_t::pbase;
55  using base_t::pptr;
56  using base_t::epptr;
57  using base_t::pbump;
58  using base_t::overflow;
60 };
61 
74 template <typename char_t, typename traits_t = std::char_traits<char_t>>
75 class fast_istreambuf_iterator
76 {
77 private:
79  stream_buffer_exposer<char_t, traits_t> * stream_buf = nullptr;
80 
81 public:
85  using difference_type = ptrdiff_t;
86  using value_type = char_t;
87  using reference = char_t;
88  using pointer = void;
89  using iterator_category = std::input_iterator_tag;
90 
95  fast_istreambuf_iterator() noexcept = default;
96  fast_istreambuf_iterator(fast_istreambuf_iterator const &) noexcept = default;
97  fast_istreambuf_iterator(fast_istreambuf_iterator &&) noexcept = default;
98  fast_istreambuf_iterator & operator=(fast_istreambuf_iterator const &) noexcept = default;
99  fast_istreambuf_iterator & operator=(fast_istreambuf_iterator &&) noexcept = default;
100  ~fast_istreambuf_iterator() noexcept = default;
101 
103  explicit fast_istreambuf_iterator(std::basic_streambuf<char_t, traits_t> & ibuf) :
104  stream_buf{reinterpret_cast<stream_buffer_exposer<char_t, traits_t> *>(&ibuf)}
105  {
106  assert(stream_buf != nullptr);
107  stream_buf->underflow(); // ensure the stream buffer has content on construction
108  }
110 
114  fast_istreambuf_iterator & operator++()
116  {
117  assert(stream_buf != nullptr);
118  if ((stream_buf->gptr() + 1) == stream_buf->egptr())
119  stream_buf->snextc(); // move right, then underflow()
120  else
121  stream_buf->gbump(1);
122  return *this;
123  }
124 
126  void operator++(int)
127  {
128  ++(*this);
129  }
131 
133  reference operator*() const
134  {
135  assert(stream_buf != nullptr);
136  return *stream_buf->gptr();
137  }
138 
143  friend bool operator==(fast_istreambuf_iterator const & lhs, std::ranges::default_sentinel_t const &) noexcept
145  {
146  assert(lhs.stream_buf != nullptr);
147  // compare size of remaining buffer; since ++ always resizes if possible, safe to compare pointers here
148  return (lhs.stream_buf->gptr() == lhs.stream_buf->egptr());
149  }
150 
152  friend bool operator!=(fast_istreambuf_iterator const & lhs, std::ranges::default_sentinel_t const &) noexcept
153  {
154  return !(lhs == std::ranges::default_sentinel);
155  }
156 
158  friend bool operator==(std::ranges::default_sentinel_t const &, fast_istreambuf_iterator const & rhs) noexcept
159  {
160  return rhs == std::ranges::default_sentinel;
161  }
162 
164  friend bool operator!=(std::ranges::default_sentinel_t const &, fast_istreambuf_iterator const & rhs) noexcept
165  {
166  return !(rhs == std::ranges::default_sentinel);
167  }
169 };
170 
171 } // namespace seqan3::detail
172 
173 namespace seqan3
174 {
175 
180 #ifdef __cpp_lib_ranges
181 
186 using SEQAN3_DOXYGEN_ONLY(ostream_iterator =) ::std::ostream_iterator;
187 
192 using SEQAN3_DOXYGEN_ONLY(ostreambuf_iterator =) ::std::ostreambuf_iterator;
193 
194 #else
195 
200 using SEQAN3_DOXYGEN_ONLY(ostream_iterator =) ::ranges::ostream_iterator;
201 
206 using SEQAN3_DOXYGEN_ONLY(ostreambuf_iterator =) ::ranges::ostreambuf_iterator;
207 
208 #endif // __cpp_lib_ranges
209 } // namespace seqan3
std::rel_ops::operator!=
T operator!=(T... args)
std::basic_streambuf::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:200
std::input_iterator_tag
std::basic_streambuf
std::basic_streambuf::pbump
T pbump(T... args)
std::basic_streambuf::eback
T eback(T... args)
std::basic_streambuf::underflow
T underflow(T... args)
std::basic_streambuf::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:206
seqan3
The main SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:36
std::basic_streambuf::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.