SeqAn3  3.0.2
The Modern C++ library for sequence analysis.
seqan3::detail::fast_ostreambuf_iterator< char_t, traits_t > Class Template Reference

Functionally the same as std::ostreambuf_iterator, but offers writing a range more efficiently. More...

#include <seqan3/io/stream/iterator.hpp>

Public Types

Associated types
using difference_type = ptrdiff_t
 Defaults to ptrdiff_t.
 
using value_type = char_t
 The char type of the stream.
 
using reference = char_t
 The char type of the stream.
 
using pointer = void
 Has no pointer type.
 
using iterator_category = std::output_iterator_tag
 

Public Member Functions

bool failed () const noexcept
 Returns true if this iterator has encountered the end-of-file condition on output,false` otherwise.
 
fast_ostreambuf_iteratoroperator* ()
 no op.
 
fast_ostreambuf_iteratoroperator= (char_t const c)
 Writes a character to the associated output stream.
 
void write_end_of_line (bool const add_cr)
 Write "\n" or "\r\n" to the stream buffer, depending on arguments. More...
 
template<arithmetic number_type>
auto write_number (number_type num)
 Writes a number to the underlying stream buffer using std::to_chars. More...
 
template<std::ranges::forward_range range_type>
auto write_range (range_type &&rng)
 Writes a range to the associated output. More...
 
Constructors, destructor and assignment
 fast_ostreambuf_iterator () noexcept=default
 Defaulted.
 
 fast_ostreambuf_iterator (fast_ostreambuf_iterator const &) noexcept=default
 Defaulted.
 
 fast_ostreambuf_iterator (fast_ostreambuf_iterator &&) noexcept=default
 Defaulted.
 
fast_ostreambuf_iteratoroperator= (fast_ostreambuf_iterator const &) noexcept=default
 Defaulted.
 
fast_ostreambuf_iteratoroperator= (fast_ostreambuf_iterator &&) noexcept=default
 Defaulted.
 
 ~fast_ostreambuf_iterator () noexcept=default
 Defaulted.
 
 fast_ostreambuf_iterator (std::basic_streambuf< char_t, traits_t > &ibuf)
 Construct from a stream buffer.
 
Arithmetic operators
fast_ostreambuf_iteratoroperator++ ()
 no op.
 
fast_ostreambuf_iteratoroperator++ (int)
 This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
 

Private Attributes

stream_buffer_exposer< char_t, traits_t > * stream_buf = nullptr
 Down-cast pointer to the stream-buffer.
 

Detailed Description

template<typename char_t, typename traits_t = std::char_traits<char_t>>
class seqan3::detail::fast_ostreambuf_iterator< char_t, traits_t >

Functionally the same as std::ostreambuf_iterator, but offers writing a range more efficiently.

Template Parameters
char_tThe stream's character type.
traits_tThe stream's traits type.

The functions seqan3::fast_ostreambuf_iterator::write_range and seqan3::fast_ostreambuf_iterator::write_n allow more efficient writing of ranges by writing in chunks that avoiding overflow checks.

#include <sstream>
int main()
{
std::string id{"seq1"};
std::string sequence{"ACTGACTGACTGACTAGCATGACTAGCATGC"};
// construct iterator from stream buffer
auto stream_it = seqan3::detail::fast_ostreambuf_iterator{*ostr.rdbuf()};
// You can do anything you could do with a regular std::ostreambuf_iterator
stream_it = '>'; // writes '>' to stream
*stream_it = ' '; // writes ' ' to stream
// Additionally, there is an efficient write_range member function
// Example 1: Write a range completely
stream_it.write_range(id); // return value can be ignored
// Example 2: Write a range in chunks of 10
auto it = std::ranges::begin(sequence);
while (it != std::ranges::end(sequence))
{
/* Note that you need cannot use stream_it.write_range(rng | seqan3::views::take(10) here
* because the returned iterator is not of the correct type.
*/
auto current_end = it;
size_t steps = std::ranges::advance(current_end, 10u, std::ranges::end(sequence));
using subrange_t = std::ranges::subrange<decltype(it), decltype(current_end), std::ranges::subrange_kind::sized>;
// Be aware that your range_type must model std::ranges::forwarding_range in order to use the return value!
it = stream_it.write_range(subrange_t{it, current_end, 10u - steps});
stream_it = ' ';
}
}

Member Typedef Documentation

◆ iterator_category

template<typename char_t , typename traits_t = std::char_traits<char_t>>
using seqan3::detail::fast_ostreambuf_iterator< char_t, traits_t >::iterator_category = std::output_iterator_tag

Pure output iterator.

Member Function Documentation

◆ write_number()

template<typename char_t , typename traits_t = std::char_traits<char_t>>
template<arithmetic number_type>
auto seqan3::detail::fast_ostreambuf_iterator< char_t, traits_t >::write_number ( number_type  num)
inline

Writes a number to the underlying stream buffer using std::to_chars.

Template Parameters
number_typeThe type of number; must model seqan3::arithmetic.
Parameters
[in]numThe number to write.

◆ write_range()

template<typename char_t , typename traits_t = std::char_traits<char_t>>
template<std::ranges::forward_range range_type>
auto seqan3::detail::fast_ostreambuf_iterator< char_t, traits_t >::write_range ( range_type &&  rng)
inline

Writes a range to the associated output.

Template Parameters
range_typeThe type of range to write; Must model std::ranges::forward_range.
Parameters
[in]rngThe range to write.
Returns
If range_type models std::ranges::forwarding_range returns an iterator pointing to end of the range (rng) else returns void.

This function avoids the buffer-at-end check by writing the range in chunks, where a chunks has the size of the remaining space in the put area of the buffer. If the range type models std::ranges::sized_range the chunks are written using std::ranges::copy_n, which may use memcpy if applicable. Otherwise, a simple for loop iterates over the chunk.

Attention
You can only use the return value (end iterator) if your range type models std::ranges::forwarding_range.

Example:

#include <sstream>
int main()
{
std::string id{"seq1"};
std::string sequence{"ACTGACTGACTGACTAGCATGACTAGCATGC"};
// construct iterator from stream buffer
auto stream_it = seqan3::detail::fast_ostreambuf_iterator{*ostr.rdbuf()};
// You can do anything you could do with a regular std::ostreambuf_iterator
stream_it = '>'; // writes '>' to stream
*stream_it = ' '; // writes ' ' to stream
// Additionally, there is an efficient write_range member function
// Example 1: Write a range completely
stream_it.write_range(id); // return value can be ignored
// Example 2: Write a range in chunks of 10
auto it = std::ranges::begin(sequence);
while (it != std::ranges::end(sequence))
{
/* Note that you need cannot use stream_it.write_range(rng | seqan3::views::take(10) here
* because the returned iterator is not of the correct type.
*/
auto current_end = it;
size_t steps = std::ranges::advance(current_end, 10u, std::ranges::end(sequence));
using subrange_t = std::ranges::subrange<decltype(it), decltype(current_end), std::ranges::subrange_kind::sized>;
// Be aware that your range_type must model std::ranges::forwarding_range in order to use the return value!
it = stream_it.write_range(subrange_t{it, current_end, 10u - steps});
stream_it = ' ';
}
}

The documentation for this class was generated from the following file:
seqan3::detail::fast_ostreambuf_iterator::write_range
auto write_range(range_type &&rng)
Writes a range to the associated output.
Definition: iterator.hpp:298
sstream
std::string
std::ostringstream
std::ranges::begin
T begin(T... args)
seqan3::detail::fast_ostreambuf_iterator
Functionally the same as std::ostreambuf_iterator, but offers writing a range more efficiently.
Definition: iterator.hpp:191
iterator.hpp
Provides seqan3::fast_istreambuf_iterator and seqan3::fast_ostreambuf_iterator, as well as,...
misc.hpp
Provides various utility functions.