24namespace seqan3::detail
38template <
typename char_t,
typename traits_t = std::
char_traits<
char_t>>
39class fast_istreambuf_iterator
43 stream_buffer_exposer<char_t, traits_t> * stream_buf =
nullptr;
52 using difference_type = ptrdiff_t;
53 using value_type = char_t;
54 using reference = char_t;
62 fast_istreambuf_iterator() noexcept = default;
63 fast_istreambuf_iterator(fast_istreambuf_iterator const &) noexcept = default;
64 fast_istreambuf_iterator(fast_istreambuf_iterator &&) noexcept = default;
65 fast_istreambuf_iterator & operator=(fast_istreambuf_iterator const &) noexcept = default;
66 fast_istreambuf_iterator & operator=(fast_istreambuf_iterator &&) noexcept = default;
67 ~fast_istreambuf_iterator() noexcept = default;
70 explicit fast_istreambuf_iterator(
std::basic_streambuf<char_t, traits_t> & ibuf) :
71 stream_buf{
reinterpret_cast<stream_buffer_exposer<char_t, traits_t> *
>(&ibuf)}
73 assert(stream_buf !=
nullptr);
75 if (stream_buf->gptr() == stream_buf->egptr())
76 stream_buf->underflow();
81 template <
typename record_type>
82 requires std::same_as<std::ranges::range_value_t<record_type>,
std::string_view>
83 void cache_record_into(
char const record_end,
char const field_sep, record_type & raw_record)
85 bool has_overflowed =
false;
87 char * data_begin = stream_buf->gptr();
88 size_t const number_of_fields = raw_record.
size();
89 size_t number_of_seen_fields = 0;
92 char const * ptr = stream_buf->gptr();
94 auto overflow_into_buffer = [&]()
96 size_t count = stream_buf->egptr() - stream_buf->gptr();
97 has_overflowed =
true;
98 overflow_buffer.resize(old_count + count);
99 std::ranges::copy(stream_buf->gptr(), stream_buf->egptr(), overflow_buffer.data() + old_count);
102 stream_buf->gbump(count);
103 stream_buf->underflow();
106 while (number_of_seen_fields < number_of_fields - 1)
108 ptr =
std::find(ptr,
static_cast<char const *
>(stream_buf->egptr()), field_sep);
110 if (ptr != stream_buf->egptr())
112 field_positions[number_of_seen_fields] = ptr - stream_buf->gptr() + old_count;
114 ++number_of_seen_fields;
118 overflow_into_buffer();
119 assert(stream_buf->gptr() != stream_buf->egptr());
120 ptr = stream_buf->gptr();
128 ptr =
std::find(ptr,
static_cast<char const *
>(stream_buf->egptr()), record_end);
130 if (ptr == stream_buf->egptr())
132 overflow_into_buffer();
133 assert(stream_buf->gptr() != stream_buf->egptr());
134 ptr = stream_buf->gptr();
138 count = ptr - stream_buf->gptr();
146 overflow_buffer.resize(old_count + count);
147 std::ranges::copy(stream_buf->gptr(), stream_buf->gptr() + count, overflow_buffer.data() + old_count);
150 data_begin = overflow_buffer.data();
153 stream_buf->gbump(count);
156 field_positions.back() = old_count +
count;
158 for (
size_t i = 1; i < number_of_fields; ++i)
159 raw_record[i] =
std::string_view{data_begin + field_positions[i - 1] + 1, data_begin + field_positions[i]};
167 if (stream_buf->egptr() - stream_buf->gptr() >= size)
170 stream_buf->gbump(size);
174 overflow_buffer.resize(size);
176 int32_t remaining_bytes{
size};
178 while (stream_buf->egptr() - stream_buf->gptr() < remaining_bytes)
182 overflow_buffer.data() + size - remaining_bytes);
183 size_t const number_of_copied_bytes = stream_buf->egptr() - stream_buf->gptr();
184 remaining_bytes -= number_of_copied_bytes;
185 stream_buf->gbump(number_of_copied_bytes);
186 stream_buf->underflow();
187 assert((remaining_bytes == 0 || stream_buf->egptr() != stream_buf->gptr())
188 &&
"I still need to read characters but my stream is at end.");
191 if (remaining_bytes != 0)
194 stream_buf->gptr() + remaining_bytes,
195 overflow_buffer.data() + size - remaining_bytes);
197 stream_buf->gbump(remaining_bytes);
200 result = {overflow_buffer.
begin(), overflow_buffer.end()};
210 fast_istreambuf_iterator & operator++()
212 assert(stream_buf !=
nullptr);
214 if ((stream_buf->gptr() + 1) == stream_buf->egptr())
215 stream_buf->snextc();
217 stream_buf->gbump(1);
229 reference operator*()
const
231 assert(stream_buf !=
nullptr);
232 return *stream_buf->gptr();
240 friend bool operator==(fast_istreambuf_iterator
const & lhs, std::default_sentinel_t
const &)
noexcept
242 assert(lhs.stream_buf !=
nullptr);
244 return (lhs.stream_buf->gptr() == lhs.stream_buf->egptr());
248 friend bool operator!=(fast_istreambuf_iterator
const & lhs, std::default_sentinel_t
const &)
noexcept
250 return !(lhs == std::default_sentinel);
254 friend bool operator==(std::default_sentinel_t
const &, fast_istreambuf_iterator
const & rhs)
noexcept
256 return rhs == std::default_sentinel;
260 friend bool operator!=(std::default_sentinel_t
const &, fast_istreambuf_iterator
const & rhs)
noexcept
262 return !(rhs == std::default_sentinel);
constexpr ptrdiff_t count
Count the occurrences of a type in a pack.
Definition: type_pack/traits.hpp:164
constexpr size_t size
The size of a type pack.
Definition: type_pack/traits.hpp:146
SeqAn specific customisations in the standard namespace.
Provides seqan3::detail::stream_buffer_exposer.