mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 18:02:05 -05:00
AK: Make DisjointChunks support FixedArray
This extracts the shatter_chunk logic, because it needs to be different for FixedArray.
This commit is contained in:
parent
ee9eef1fa8
commit
4ec599aae5
1 changed files with 44 additions and 12 deletions
|
@ -11,6 +11,7 @@
|
|||
#include <AK/Forward.h>
|
||||
#include <AK/Span.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Try.h>
|
||||
|
||||
namespace AK {
|
||||
|
||||
|
@ -185,6 +186,48 @@ private:
|
|||
Vector<Span<T>> m_spans;
|
||||
};
|
||||
|
||||
namespace Detail {
|
||||
|
||||
template<typename T, typename ChunkType>
|
||||
ChunkType shatter_chunk(ChunkType& source_chunk, size_t start, size_t sliced_length)
|
||||
{
|
||||
auto wanted_slice = source_chunk.span().slice(start, sliced_length);
|
||||
|
||||
ChunkType new_chunk;
|
||||
if constexpr (IsTriviallyConstructible<T>) {
|
||||
new_chunk.resize(wanted_slice.size());
|
||||
|
||||
TypedTransfer<T>::move(new_chunk.data(), wanted_slice.data(), wanted_slice.size());
|
||||
} else {
|
||||
new_chunk.ensure_capacity(wanted_slice.size());
|
||||
for (auto& entry : wanted_slice)
|
||||
new_chunk.unchecked_append(move(entry));
|
||||
}
|
||||
source_chunk.remove(start, sliced_length);
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
FixedArray<T> shatter_chunk(FixedArray<T>& source_chunk, size_t start, size_t sliced_length)
|
||||
{
|
||||
auto wanted_slice = source_chunk.span().slice(start, sliced_length);
|
||||
|
||||
FixedArray<T> new_chunk = FixedArray<T>::must_create_but_fixme_should_propagate_errors(wanted_slice.size());
|
||||
if constexpr (IsTriviallyConstructible<T>) {
|
||||
TypedTransfer<T>::move(new_chunk.data(), wanted_slice.data(), wanted_slice.size());
|
||||
} else {
|
||||
// FIXME: propagate errors
|
||||
auto copied_chunk = MUST(FixedArray<T>::try_create(wanted_slice));
|
||||
new_chunk.swap(copied_chunk);
|
||||
}
|
||||
// FIXME: propagate errors
|
||||
auto rest_of_chunk = MUST(FixedArray<T>::try_create(source_chunk.span().slice(start)));
|
||||
source_chunk.swap(rest_of_chunk);
|
||||
return new_chunk;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T, typename ChunkType = Vector<T>>
|
||||
class DisjointChunks {
|
||||
public:
|
||||
|
@ -309,20 +352,9 @@ public:
|
|||
result.m_chunks.append(move(chunk));
|
||||
} else {
|
||||
// Shatter the chunk, we were asked for only a part of it :(
|
||||
auto wanted_slice = chunk.span().slice(start, sliced_length);
|
||||
auto new_chunk = Detail::shatter_chunk<T>(chunk, start, sliced_length);
|
||||
|
||||
ChunkType new_chunk;
|
||||
if constexpr (IsTriviallyConstructible<T>) {
|
||||
new_chunk.resize(wanted_slice.size());
|
||||
TypedTransfer<T>::move(new_chunk.data(), wanted_slice.data(), wanted_slice.size());
|
||||
} else {
|
||||
new_chunk.ensure_capacity(wanted_slice.size());
|
||||
for (auto& entry : wanted_slice)
|
||||
new_chunk.unchecked_append(move(entry));
|
||||
}
|
||||
result.m_chunks.append(move(new_chunk));
|
||||
|
||||
chunk.remove(start, sliced_length);
|
||||
}
|
||||
start = 0;
|
||||
length -= sliced_length;
|
||||
|
|
Loading…
Add table
Reference in a new issue