21namespace seqan3::detail
35template <
typename char_t,
typename traits_t = std::
char_traits<
char_t>>
36class fast_istreambuf_iterator
40 stream_buffer_exposer<char_t, traits_t> * stream_buf =
nullptr;
49 using difference_type = ptrdiff_t;
50 using value_type = char_t;
51 using reference = char_t;
59 fast_istreambuf_iterator() noexcept = default;
60 fast_istreambuf_iterator(fast_istreambuf_iterator const &) noexcept = default;
61 fast_istreambuf_iterator(fast_istreambuf_iterator &&) noexcept = default;
62 fast_istreambuf_iterator & operator=(fast_istreambuf_iterator const &) noexcept = default;
63 fast_istreambuf_iterator & operator=(fast_istreambuf_iterator &&) noexcept = default;
64 ~fast_istreambuf_iterator() noexcept = default;
67 explicit fast_istreambuf_iterator(
std::basic_streambuf<char_t, traits_t> & ibuf) :
68 stream_buf{
reinterpret_cast<stream_buffer_exposer<char_t, traits_t> *
>(&ibuf)}
70 assert(stream_buf !=
nullptr);
72 if (stream_buf->gptr() == stream_buf->egptr())
73 stream_buf->underflow();
78 template <
typename record_type>
79 requires std::same_as<std::ranges::range_value_t<record_type>,
std::string_view>
80 void cache_record_into(
char const record_end,
char const field_sep, record_type & raw_record)
82 bool has_overflowed =
false;
84 char * data_begin = stream_buf->gptr();
85 size_t const number_of_fields = raw_record.
size();
86 size_t number_of_seen_fields = 0;
89 char const * ptr = stream_buf->gptr();
91 auto overflow_into_buffer = [&]()
93 size_t count = stream_buf->egptr() - stream_buf->gptr();
94 has_overflowed =
true;
95 overflow_buffer.resize(old_count + count);
96 std::ranges::copy(stream_buf->gptr(), stream_buf->egptr(), overflow_buffer.data() + old_count);
99 stream_buf->gbump(count);
100 stream_buf->underflow();
103 while (number_of_seen_fields < number_of_fields - 1)
105 ptr =
std::find(ptr,
static_cast<char const *
>(stream_buf->egptr()), field_sep);
107 if (ptr != stream_buf->egptr())
109 field_positions[number_of_seen_fields] = ptr - stream_buf->gptr() + old_count;
111 ++number_of_seen_fields;
115 overflow_into_buffer();
116 assert(stream_buf->gptr() != stream_buf->egptr());
117 ptr = stream_buf->gptr();
125 ptr =
std::find(ptr,
static_cast<char const *
>(stream_buf->egptr()), record_end);
127 if (ptr == stream_buf->egptr())
129 overflow_into_buffer();
130 assert(stream_buf->gptr() != stream_buf->egptr());
131 ptr = stream_buf->gptr();
135 count = ptr - stream_buf->gptr();
143 overflow_buffer.resize(old_count + count);
144 std::ranges::copy(stream_buf->gptr(), stream_buf->gptr() + count, overflow_buffer.data() + old_count);
147 data_begin = overflow_buffer.data();
150 stream_buf->gbump(count);
153 field_positions.back() = old_count +
count;
155 for (
size_t i = 1; i < number_of_fields; ++i)
156 raw_record[i] =
std::string_view{data_begin + field_positions[i - 1] + 1, data_begin + field_positions[i]};
164 if (stream_buf->egptr() - stream_buf->gptr() >= size)
167 stream_buf->gbump(size);
171 overflow_buffer.resize(size);
173 int32_t remaining_bytes{
size};
175 while (stream_buf->egptr() - stream_buf->gptr() < remaining_bytes)
179 overflow_buffer.data() + size - remaining_bytes);
180 size_t const number_of_copied_bytes = stream_buf->egptr() - stream_buf->gptr();
181 remaining_bytes -= number_of_copied_bytes;
182 stream_buf->gbump(number_of_copied_bytes);
183 stream_buf->underflow();
184 assert((remaining_bytes == 0 || stream_buf->egptr() != stream_buf->gptr())
185 &&
"I still need to read characters but my stream is at end.");
188 if (remaining_bytes != 0)
191 stream_buf->gptr() + remaining_bytes,
192 overflow_buffer.data() + size - remaining_bytes);
194 stream_buf->gbump(remaining_bytes);
197 result = {overflow_buffer.
begin(), overflow_buffer.end()};
207 fast_istreambuf_iterator & operator++()
209 assert(stream_buf !=
nullptr);
211 if ((stream_buf->gptr() + 1) == stream_buf->egptr())
212 stream_buf->snextc();
214 stream_buf->gbump(1);
226 reference operator*()
const
228 assert(stream_buf !=
nullptr);
229 assert(stream_buf->gptr() != stream_buf->egptr());
230 return *stream_buf->gptr();
238 friend bool operator==(fast_istreambuf_iterator
const & lhs, std::default_sentinel_t
const &)
noexcept
240 assert(lhs.stream_buf !=
nullptr);
242 return (lhs.stream_buf->gptr() == lhs.stream_buf->egptr());
246 friend bool operator!=(fast_istreambuf_iterator
const & lhs, std::default_sentinel_t
const &)
noexcept
248 return !(lhs == std::default_sentinel);
252 friend bool operator==(std::default_sentinel_t
const &, fast_istreambuf_iterator
const & rhs)
noexcept
254 return rhs == std::default_sentinel;
258 friend bool operator!=(std::default_sentinel_t
const &, fast_istreambuf_iterator
const & rhs)
noexcept
260 return !(rhs == std::default_sentinel);
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition type_pack/traits.hpp:161
constexpr size_t size
The size of a type pack.
Definition type_pack/traits.hpp:143
SeqAn specific customisations in the standard namespace.
Provides seqan3::detail::stream_buffer_exposer.