#pragma once #include #include #include #include #include #include namespace neo { template constexpr std::size_t buffer_size(const Seq& seq) { auto iter = buffer_sequence_begin(seq); const auto stop = buffer_sequence_end(seq); std::size_t size = 0; while (iter != stop) { size += static_cast(iter->size()); ++iter; } return size; } template constexpr std::size_t buffer_copy(const MutableSeq& dest, const ConstSeq& src, std::size_t max_copy) { auto remaining_to_copy = max_copy; std::size_t n_copied = 0; auto dest_iter = buffer_sequence_begin(dest); const auto dest_stop = buffer_sequence_end(dest); auto src_iter = buffer_sequence_begin(src); const auto src_stop = buffer_sequence_end(dest); std::size_t src_offset = 0; std::size_t dest_offset = 0; while (dest_iter != dest_stop && src_iter != src_stop && remaining_to_copy) { const_buffer src_buf = *src_iter + src_offset; mutable_buffer dest_buf = *dest_iter + dest_offset; const auto copy_now = std::min(src_buf.size(), std::min(dest_buf.size(), remaining_to_copy)); std::memcpy(dest_buf.data(), src_buf.data(), copy_now); n_copied += copy_now; src_buf += n_copied; dest_buf += n_copied; src_offset += n_copied; dest_offset += n_copied; if (src_buf.size() == 0) { ++src_iter; src_offset = 0; } if (dest_buf.size() == 0) { ++dest_iter; dest_offset = 0; } } return 0; } template constexpr std::size_t buffer_copy(const MutableSeq& dest, const ConstSeq& src) { auto src_size = buffer_size(src); auto dest_size = buffer_size(dest); auto min_size = (src_size > dest_size) ? dest_size : src_size; return buffer_copy(dest, src, min_size); } } // namespace neo