Coverage Report

Created: 2025-12-18 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/AK/SegmentedVector.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/OwnPtr.h>
10
#include <AK/Vector.h>
11
12
namespace AK {
13
14
template<typename T, int segment_size = 512>
15
class SegmentedVector {
16
private:
17
    using VisibleType = RemoveReference<T>;
18
    static constexpr bool contains_reference = IsLvalueReference<T>;
19
20
public:
21
0
    SegmentedVector() = default;
22
23
0
    size_t size() const { return m_size; }
24
    bool is_empty() const { return m_size == 0; }
25
26
    using Iterator = SimpleIterator<SegmentedVector, VisibleType>;
27
    using ConstIterator = SimpleIterator<SegmentedVector const, VisibleType const>;
28
29
0
    Iterator begin() { return Iterator::begin(*this); }
30
0
    ConstIterator begin() const { return ConstIterator::begin(*this); }
31
0
    Iterator end() { return Iterator::end(*this); }
32
0
    ConstIterator end() const { return ConstIterator::end(*this); }
33
34
    ALWAYS_INLINE VisibleType const& at(size_t i) const
35
0
    {
36
0
        VERIFY(i < m_size);
37
0
        auto segment_index = i / segment_size;
38
0
        auto index_in_segment = i % segment_size;
39
0
        return m_segments[segment_index]->at(index_in_segment);
40
0
    }
41
42
    ALWAYS_INLINE VisibleType& at(size_t i)
43
0
    {
44
0
        VERIFY(i < m_size);
45
0
        auto segment_index = i / segment_size;
46
0
        auto index_in_segment = i % segment_size;
47
0
        return m_segments[segment_index]->at(index_in_segment);
48
0
    }
49
50
0
    ALWAYS_INLINE VisibleType const& operator[](size_t i) const { return at(i); }
51
0
    ALWAYS_INLINE VisibleType& operator[](size_t i) { return at(i); }
52
53
    void append(T&& value)
54
0
    {
55
0
        if (m_segments.is_empty() || m_segments.last()->size() >= segment_size)
56
0
            m_segments.append(make<Vector<T, segment_size>>());
57
58
        if constexpr (contains_reference) {
59
            m_segments.last()->append(value);
60
0
        } else {
61
0
            m_segments.last()->append(move(value));
62
0
        }
63
0
        ++m_size;
64
0
    }
65
66
private:
67
    Vector<NonnullOwnPtr<Vector<T, segment_size>>> m_segments;
68
    size_t m_size { 0 };
69
};
70
71
}