/// Size is the number of buffers to keep around. It should be
 /// larger than the number of thread expected to read from this
 /// class. nb_sequences is the number of sequences to read into a
 /// buffer. 'begin' and 'end' are iterators to a range of istream.
 whole_sequence_parser(uint32_t size, uint32_t nb_sequences,
                       uint32_t max_producers, StreamIterator& streams) :
   super(max_producers, size),
   streams_(max_producers),
   streams_iterator_(streams)
 {
   for(auto it = super::element_begin(); it != super::element_end(); ++it) {
     it->nb_filled = 0;
     it->data.resize(nb_sequences);
   }
   for(uint32_t i = 0; i < max_producers; ++i) {
     streams_.init(i);
     open_next_file(streams_[i]);
   }
 }
 /// Max_producers is the maximum number of concurrent threads than
 /// can produce data simultaneously. Size is the number of buffer to
 /// keep around. It should be larger than the number of thread
 /// expected to read from this class. buf_size is the size of each
 /// buffer. A StreamIterator is expected to have a next() method,
 /// which is thread safe, and which returns (move) a
 /// std::unique<std::istream> object.
 mer_overlap_sequence_parser(uint16_t mer_len, uint32_t max_producers, uint32_t size, size_t buf_size,
                             StreamIterator& streams) :
   super(max_producers, size),
   mer_len_(mer_len),
   buf_size_(buf_size),
   buffer(new char[size * buf_size]),
   seam_buffer(new char[max_producers * (mer_len - 1)]),
   streams_(max_producers),
   streams_iterator_(streams),
   files_read_(0), reads_read_(0)
 {
   for(sequence_ptr* it = super::element_begin(); it != super::element_end(); ++it)
     it->start = it->end = buffer + (it - super::element_begin()) * buf_size;
   for(uint32_t i = 0; i < max_producers; ++i) {
     streams_.init(i);
     streams_[i].seam = seam_buffer + i * (mer_len - 1);
     open_next_file(streams_[i]);
   }
 }