mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 12:23:15 +00: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
|
@ -11,6 +11,7 @@
|
||||||
#include <AK/Forward.h>
|
#include <AK/Forward.h>
|
||||||
#include <AK/Span.h>
|
#include <AK/Span.h>
|
||||||
#include <AK/StdLibExtras.h>
|
#include <AK/StdLibExtras.h>
|
||||||
|
#include <AK/Try.h>
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
|
||||||
|
@ -185,6 +186,48 @@ private:
|
||||||
Vector<Span<T>> m_spans;
|
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>>
|
template<typename T, typename ChunkType = Vector<T>>
|
||||||
class DisjointChunks {
|
class DisjointChunks {
|
||||||
public:
|
public:
|
||||||
|
@ -309,20 +352,9 @@ public:
|
||||||
result.m_chunks.append(move(chunk));
|
result.m_chunks.append(move(chunk));
|
||||||
} else {
|
} else {
|
||||||
// Shatter the chunk, we were asked for only a part of it :(
|
// 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));
|
result.m_chunks.append(move(new_chunk));
|
||||||
|
|
||||||
chunk.remove(start, sliced_length);
|
|
||||||
}
|
}
|
||||||
start = 0;
|
start = 0;
|
||||||
length -= sliced_length;
|
length -= sliced_length;
|
||||||
|
|
Loading…
Reference in a new issue