27 namespace seqan3::detail
43 template <
typename char_t,
typename traits_t = std::
char_traits<
char_t>>
77 template <
typename char_t,
typename traits_t = std::
char_traits<
char_t>>
78 class fast_istreambuf_iterator
82 stream_buffer_exposer<char_t, traits_t> * stream_buf =
nullptr;
88 using difference_type = ptrdiff_t;
89 using value_type = char_t;
90 using reference = char_t;
98 fast_istreambuf_iterator() noexcept = default;
99 fast_istreambuf_iterator(fast_istreambuf_iterator const &) noexcept = default;
100 fast_istreambuf_iterator(fast_istreambuf_iterator &&) noexcept = default;
101 fast_istreambuf_iterator & operator=(fast_istreambuf_iterator const &) noexcept = default;
102 fast_istreambuf_iterator & operator=(fast_istreambuf_iterator &&) noexcept = default;
103 ~fast_istreambuf_iterator() noexcept = default;
106 explicit fast_istreambuf_iterator(
std::basic_streambuf<char_t, traits_t> & ibuf) :
107 stream_buf{
reinterpret_cast<stream_buffer_exposer<char_t, traits_t> *
>(&ibuf)}
109 assert(stream_buf !=
nullptr);
110 stream_buf->underflow();
117 fast_istreambuf_iterator & operator++()
120 assert(stream_buf !=
nullptr);
121 if ((stream_buf->gptr() + 1) == stream_buf->egptr())
122 stream_buf->snextc();
124 stream_buf->gbump(1);
136 reference operator*()
const
138 assert(stream_buf !=
nullptr);
139 return *stream_buf->gptr();
146 friend bool operator==(fast_istreambuf_iterator
const & lhs, std::default_sentinel_t
const &) noexcept
149 assert(lhs.stream_buf !=
nullptr);
151 return (lhs.stream_buf->gptr() == lhs.stream_buf->egptr());
155 friend bool operator!=(fast_istreambuf_iterator
const & lhs, std::default_sentinel_t
const &) noexcept
157 return !(lhs == std::default_sentinel);
161 friend bool operator==(std::default_sentinel_t
const &, fast_istreambuf_iterator
const & rhs) noexcept
163 return rhs == std::default_sentinel;
167 friend bool operator!=(std::default_sentinel_t
const &, fast_istreambuf_iterator
const & rhs) noexcept
169 return !(rhs == std::default_sentinel);
186 template <
typename char_t,
typename traits_t = std::
char_traits<
char_t>>
187 class fast_ostreambuf_iterator
191 stream_buffer_exposer<char_t, traits_t> * stream_buf =
nullptr;
197 using difference_type = ptrdiff_t;
198 using value_type = char_t;
199 using reference = char_t;
200 using pointer = void;
207 fast_ostreambuf_iterator() noexcept = default;
208 fast_ostreambuf_iterator(fast_ostreambuf_iterator const &) noexcept = default;
209 fast_ostreambuf_iterator(fast_ostreambuf_iterator &&) noexcept = default;
210 fast_ostreambuf_iterator & operator=(fast_ostreambuf_iterator const &) noexcept = default;
211 fast_ostreambuf_iterator & operator=(fast_ostreambuf_iterator &&) noexcept = default;
212 ~fast_ostreambuf_iterator() noexcept = default;
215 explicit fast_ostreambuf_iterator(
std::basic_streambuf<char_t, traits_t> & ibuf) :
216 stream_buf{
reinterpret_cast<stream_buffer_exposer<char_t, traits_t> *
>(&ibuf)}
218 assert(stream_buf !=
nullptr);
219 if (stream_buf->pptr() == stream_buf->epptr())
220 stream_buf->overflow();
227 fast_ostreambuf_iterator & operator++()
233 fast_ostreambuf_iterator & operator++(
int)
240 fast_ostreambuf_iterator & operator*()
246 fast_ostreambuf_iterator & operator=(char_t
const c)
248 assert(stream_buf !=
nullptr);
249 if (stream_buf->pptr() == stream_buf->epptr())
251 if (stream_buf->sputc(c) == traits_t::eof())
260 *stream_buf->pptr() = c;
261 stream_buf->pbump(1);
267 bool failed() const noexcept
269 return stream_buf->overflow() == traits_t::eof();
290 template <std::ranges::forward_range range_type>
292 requires std::ranges::borrowed_range<range_type>
294 auto write_range(range_type && rng)
296 using sen_t = std::ranges::sentinel_t<range_type>;
297 using it_t = std::ranges::iterator_t<range_type>;
300 sen_t
end = std::ranges::end(rng);
304 size_t const buffer_space = stream_buf->epptr() - stream_buf->pptr();
306 if constexpr (std::ranges::sized_range<range_type>)
308 size_t const characters_to_write = std::min<size_t>(std::ranges::distance(it, end), buffer_space);
309 auto copy_res = std::ranges::copy_n(it, characters_to_write, stream_buf->pptr());
311 stream_buf->pbump(characters_to_write);
316 for (; it !=
end && i < buffer_space; ++it, ++i)
317 *stream_buf->pptr() = *it;
318 stream_buf->pbump(i);
325 if (stream_buf->overflow(*it) == traits_t::eof())
340 template <std::ranges::forward_range range_type>
341 void write_range(range_type && rng)
351 template <arithmetic number_type>
352 auto write_number(number_type num)
354 if (stream_buf->epptr() - stream_buf->pptr() > 300)
356 auto res =
std::to_chars(stream_buf->pptr(), stream_buf->epptr(), num);
357 stream_buf->pbump(res.ptr - stream_buf->pptr());
362 auto res =
std::to_chars(&arithmetic_buffer[0], &arithmetic_buffer[0] +
sizeof(arithmetic_buffer), num);
363 write_range(std::ranges::subrange<char *, char *>(&arithmetic_buffer[0], res.ptr));
371 void write_end_of_line(
bool const add_cr)