SeqAn3  3.0.0
The Modern C++ library for sequence analysis.
istreambuf.hpp
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------------------------------
2 // Copyright (c) 2006-2019, Knut Reinert & Freie Universität Berlin
3 // Copyright (c) 2016-2019, 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 <iosfwd>
16 
18 #include <seqan3/std/iterator>
19 #include <seqan3/std/ranges>
20 
21 namespace seqan3::detail
22 {
23 
24 // ============================================================================
25 // fast_istreambuf_iterator
26 // ============================================================================
27 
29 template <typename char_t, typename traits_t = std::char_traits<char_t>>
30 struct stream_buffer_exposer : public std::basic_streambuf<char_t, traits_t>
31 {
34 
35  // Expose protected members:
36  using base_t::eback;
37  using base_t::gptr;
38  using base_t::egptr;
39  using base_t::gbump;
40  using base_t::underflow;
41 
42  using base_t::pbase;
43  using base_t::pptr;
44  using base_t::epptr;
45  using base_t::pbump;
46  using base_t::overflow;
47 };
48 
60 template <typename char_t, typename traits_t = std::char_traits<char_t>>
61 class fast_istreambuf_iterator
62 {
63 private:
65  stream_buffer_exposer<char_t, traits_t> * stream_buf = nullptr;
66 
67 public:
71  using difference_type = ptrdiff_t;
72  using value_type = char_t;
73  using reference = char_t;
74  using pointer = void;
75  using iterator_category = std::input_iterator_tag;
76 
81  fast_istreambuf_iterator() noexcept = default;
82  fast_istreambuf_iterator(fast_istreambuf_iterator const &) noexcept = default;
83  fast_istreambuf_iterator(fast_istreambuf_iterator &&) noexcept = default;
84  fast_istreambuf_iterator & operator=(fast_istreambuf_iterator const &) noexcept = default;
85  fast_istreambuf_iterator & operator=(fast_istreambuf_iterator &&) noexcept = default;
86  ~fast_istreambuf_iterator() noexcept = default;
87 
89  explicit fast_istreambuf_iterator(std::basic_streambuf<char_t, traits_t> & ibuf) :
90  stream_buf{reinterpret_cast<stream_buffer_exposer<char_t, traits_t> *>(&ibuf)}
91  {
92  assert(stream_buf != nullptr);
93  stream_buf->underflow(); // ensure the stream buffer has content on construction
94  }
96 
100  fast_istreambuf_iterator & operator++()
102  {
103  assert(stream_buf != nullptr);
104  stream_buf->snextc(); // move to then right, then underflow()
105  return *this;
106  }
107 
109  void operator++(int)
110  {
111  ++(*this);
112  }
114 
116  reference operator*() const
117  {
118  assert(stream_buf != nullptr);
119  return *stream_buf->gptr();
120  }
121 
126  friend bool operator==(fast_istreambuf_iterator const & lhs, std::ranges::default_sentinel_t const &) noexcept
128  {
129  assert(lhs.stream_buf != nullptr);
130  // compare size of remaining buffer; since ++ always resizes if possible, safe to compare pointers here
131  return (lhs.stream_buf->gptr() == lhs.stream_buf->egptr());
132  }
133 
135  friend bool operator!=(fast_istreambuf_iterator const & lhs, std::ranges::default_sentinel_t const &) noexcept
136  {
137  return !(lhs == std::ranges::default_sentinel);
138  }
139 
141  friend bool operator==(std::ranges::default_sentinel_t const &, fast_istreambuf_iterator const & rhs) noexcept
142  {
143  return rhs == std::ranges::default_sentinel;
144  }
145 
147  friend bool operator!=(std::ranges::default_sentinel_t const &, fast_istreambuf_iterator const & rhs) noexcept
148  {
149  return !(rhs == std::ranges::default_sentinel);
150  }
152 };
153 
154 // ============================================================================
155 // istreambuf_fn (adaptor definition)
156 // ============================================================================
157 
159 struct istreambuf_fn
160 {
167  template <typename stream_char_t, typename stream_traits_t>
168  constexpr auto operator()(std::basic_streambuf<stream_char_t, stream_traits_t> & s) const
169  {
172  {
173  detail::fast_istreambuf_iterator<stream_char_t, stream_traits_t>{s},
175  };
176  }
177 
183  template <IStream2 stream_t>
184  constexpr auto operator()(stream_t & s) const
185  {
186  return this->operator()(*s.rdbuf());
187  }
188 };
189 
190 } // namespace seqan3::detail
191 
192 // ============================================================================
193 // view::istreambuf (adaptor instance definition)
194 // ============================================================================
195 
196 namespace seqan3::view
197 {
198 
245 inline constexpr auto istreambuf = detail::istreambuf_fn{};
247 
248 } // namespace seqan3::view
::ranges::default_sentinel default_sentinel
Alias for ranges::default_sentinel. Empty sentinel object for use with iterators that know the bound ...
Definition: iterator:346
::ranges::subrange< it_t, sen_t, k > subrange
Create a view from a pair of iterator and sentinel.
Definition: ranges:339
T operator!=(T... args)
Provides C++20 additions to the <iterator> header.
SeqAn specific customisations in the standard namespace.
constexpr auto istreambuf
A view factory that returns a view over the stream buffer of an input stream.
Definition: istreambuf.hpp:245
Adaptations of concepts from the Ranges TS.
The SeqAn3 namespace for views.
Definition: aligned_sequence_concept.hpp:35
Stream concepts.
::ranges::default_sentinel_t default_sentinel_t
Alias for ranges::default_sentinel_t. Type of ranges::default_sentinel.
Definition: iterator:351