AK: Add Disjoint(Chunks Spans)::find(index)
For when the may or may not be out of bounds.
This commit is contained in:
parent
c417374dd6
commit
2df54a7b56
Notes:
sideshowbarker
2024-07-17 22:27:24 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/2df54a7b56a Pull-request: https://github.com/SerenityOS/serenity/pull/11347 Reviewed-by: https://github.com/awesomekling
1 changed files with 45 additions and 10 deletions
|
@ -99,10 +99,21 @@ public:
|
|||
T const& operator[](size_t index) const { return at(index); }
|
||||
T const& at(size_t index) const { return const_cast<DisjointSpans&>(*this).at(index); }
|
||||
T& at(size_t index)
|
||||
{
|
||||
auto value = find(index);
|
||||
VERIFY(value != nullptr);
|
||||
return *value;
|
||||
}
|
||||
T* find(size_t index)
|
||||
{
|
||||
auto span_and_offset = span_around(index);
|
||||
VERIFY(span_and_offset.offset < span_and_offset.span.size());
|
||||
return span_and_offset.span.at(span_and_offset.offset);
|
||||
if (span_and_offset.offset >= span_and_offset.span.size())
|
||||
return nullptr;
|
||||
return &span_and_offset.span.at(span_and_offset.offset);
|
||||
}
|
||||
T const* find(size_t index) const
|
||||
{
|
||||
return const_cast<DisjointSpans*>(this)->find(index);
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
|
@ -194,7 +205,12 @@ public:
|
|||
if (m_chunks.size() == 1)
|
||||
return m_chunks.first().insert(index, value);
|
||||
auto chunk_and_offset = chunk_around(index);
|
||||
chunk_and_offset.chunk.insert(chunk_and_offset.offset, move(value));
|
||||
if (!chunk_and_offset.chunk) {
|
||||
m_chunks.empend();
|
||||
chunk_and_offset.chunk = &m_chunks.last();
|
||||
}
|
||||
|
||||
chunk_and_offset.chunk->insert(chunk_and_offset.offset, move(value));
|
||||
}
|
||||
|
||||
void clear() { m_chunks.clear(); }
|
||||
|
@ -204,11 +220,27 @@ public:
|
|||
T const& at(size_t index) const { return const_cast<DisjointChunks&>(*this).at(index); }
|
||||
T& at(size_t index)
|
||||
{
|
||||
if (m_chunks.size() == 1)
|
||||
return m_chunks.first().at(index);
|
||||
auto value = find(index);
|
||||
VERIFY(value != nullptr);
|
||||
return *value;
|
||||
}
|
||||
|
||||
T* find(size_t index)
|
||||
{
|
||||
if (m_chunks.size() == 1) {
|
||||
if (m_chunks.first().size() > index)
|
||||
return &m_chunks.first().at(index);
|
||||
return nullptr;
|
||||
}
|
||||
auto chunk_and_offset = chunk_around(index);
|
||||
VERIFY(chunk_and_offset.offset < chunk_and_offset.chunk.size());
|
||||
return chunk_and_offset.chunk.at(chunk_and_offset.offset);
|
||||
if (!chunk_and_offset.chunk || chunk_and_offset.offset >= chunk_and_offset.chunk->size())
|
||||
return nullptr;
|
||||
return &chunk_and_offset.chunk->at(chunk_and_offset.offset);
|
||||
}
|
||||
|
||||
T const* find(size_t index) const
|
||||
{
|
||||
return const_cast<DisjointChunks*>(this)->find(index);
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
|
@ -319,11 +351,14 @@ public:
|
|||
|
||||
private:
|
||||
struct ChunkAndOffset {
|
||||
ChunkType& chunk;
|
||||
ChunkType* chunk;
|
||||
size_t offset;
|
||||
};
|
||||
ChunkAndOffset chunk_around(size_t index)
|
||||
{
|
||||
if (m_chunks.is_empty())
|
||||
return { nullptr, index };
|
||||
|
||||
size_t offset = 0;
|
||||
for (auto& chunk : m_chunks) {
|
||||
if (chunk.is_empty())
|
||||
|
@ -334,10 +369,10 @@ private:
|
|||
continue;
|
||||
}
|
||||
|
||||
return { chunk, index - offset };
|
||||
return { &chunk, index - offset };
|
||||
}
|
||||
|
||||
return { m_chunks.last(), index - (offset - m_chunks.last().size()) };
|
||||
return { &m_chunks.last(), index - (offset - m_chunks.last().size()) };
|
||||
}
|
||||
|
||||
Vector<ChunkType> m_chunks;
|
||||
|
|
Loading…
Add table
Reference in a new issue