AK: Make DisjointChunks support FixedArray

This extracts the shatter_chunk logic, because it needs to be different
for FixedArray.
This commit is contained in:
kleines Filmröllchen 2022-02-18 16:39:48 +01:00 committed by Ali Mohammad Pur
parent ee9eef1fa8
commit 4ec599aae5

View file

@ -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;