diff --git a/AK/DisjointChunks.h b/AK/DisjointChunks.h index 625b97554c..e991ba8c83 100644 --- a/AK/DisjointChunks.h +++ b/AK/DisjointChunks.h @@ -11,6 +11,7 @@ #include #include #include +#include namespace AK { @@ -185,6 +186,48 @@ private: Vector> m_spans; }; +namespace Detail { + +template +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) { + new_chunk.resize(wanted_slice.size()); + + TypedTransfer::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 +FixedArray shatter_chunk(FixedArray& source_chunk, size_t start, size_t sliced_length) +{ + auto wanted_slice = source_chunk.span().slice(start, sliced_length); + + FixedArray new_chunk = FixedArray::must_create_but_fixme_should_propagate_errors(wanted_slice.size()); + if constexpr (IsTriviallyConstructible) { + TypedTransfer::move(new_chunk.data(), wanted_slice.data(), wanted_slice.size()); + } else { + // FIXME: propagate errors + auto copied_chunk = MUST(FixedArray::try_create(wanted_slice)); + new_chunk.swap(copied_chunk); + } + // FIXME: propagate errors + auto rest_of_chunk = MUST(FixedArray::try_create(source_chunk.span().slice(start))); + source_chunk.swap(rest_of_chunk); + return new_chunk; +} + +} + template> 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(chunk, start, sliced_length); - ChunkType new_chunk; - if constexpr (IsTriviallyConstructible) { - new_chunk.resize(wanted_slice.size()); - TypedTransfer::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;