util/CircularBuffer: add method MoveTo()

This implements wraparound, so AsyncInputStream and ThreadInputStream
can now return all of the buffer contents in one Read() call.
This commit is contained in:
Max Kellermann
2025-01-29 21:04:52 +01:00
parent 950f5f4d32
commit e06d775af5
3 changed files with 39 additions and 12 deletions
+35
View File
@@ -3,6 +3,7 @@
#pragma once
#include <algorithm> // for std::move()
#include <cassert>
#include <cstddef>
#include <span>
@@ -153,4 +154,38 @@ public:
if (head == buffer.size())
head = 0;
}
/**
* Move data from the buffer to the destination. This method
* considers ring buffer wraparound.
*
* @return the number of items moved
*/
constexpr size_type MoveTo(Range dest) noexcept {
size_type n = 0;
auto a = Read();
if (a.size() > dest.size())
a = a.first(dest.size());
if (!a.empty()) {
dest = {std::move(a.begin(), a.end(), dest.begin()), dest.end()};
Consume(a.size());
n += a.size();
if (dest.empty())
return n;
if (auto b = Read(); !b.empty()) {
if (b.size() > dest.size())
b = b.first(dest.size());
std::move(b.begin(), b.end(), dest.begin());
Consume(b.size());
n += b.size();
}
}
return n;
}
};