Coverage Report

Created: 2025-12-18 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/AK/COWVector.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2021-2024, Ali Mohammad Pur <mpfard@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/NonnullRefPtr.h>
10
#include <AK/RefCounted.h>
11
#include <AK/Vector.h>
12
13
namespace AK {
14
15
template<typename T>
16
class COWVector {
17
    struct Detail : RefCounted<Detail> {
18
        Vector<T> m_members;
19
    };
20
21
public:
22
    COWVector()
23
178M
        : m_detail(make_ref_counted<Detail>())
24
178M
    {
25
178M
    }
AK::COWVector<regex::Match>::COWVector()
Line
Count
Source
23
59.4M
        : m_detail(make_ref_counted<Detail>())
24
59.4M
    {
25
59.4M
    }
AK::COWVector<AK::Vector<regex::Match, 0ul> >::COWVector()
Line
Count
Source
23
59.4M
        : m_detail(make_ref_counted<Detail>())
24
59.4M
    {
25
59.4M
    }
AK::COWVector<unsigned long>::COWVector()
Line
Count
Source
23
59.4M
        : m_detail(make_ref_counted<Detail>())
24
59.4M
    {
25
59.4M
    }
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::COWVector()
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::COWVector()
Unexecuted instantiation: AK::COWVector<Wasm::MemoryType>::COWVector()
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::COWVector()
Unexecuted instantiation: AK::COWVector<bool>::COWVector()
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::COWVector()
26
27
    COWVector(std::initializer_list<T> entries)
28
        : m_detail(make_ref_counted<Detail>())
29
    {
30
        for (auto& entry : entries)
31
            m_detail->m_members.append(entry);
32
    }
33
34
177M
    COWVector(COWVector const&) = default;
AK::COWVector<regex::Match>::COWVector(AK::COWVector<regex::Match> const&)
Line
Count
Source
34
59.0M
    COWVector(COWVector const&) = default;
AK::COWVector<AK::Vector<regex::Match, 0ul> >::COWVector(AK::COWVector<AK::Vector<regex::Match, 0ul> > const&)
Line
Count
Source
34
59.0M
    COWVector(COWVector const&) = default;
AK::COWVector<unsigned long>::COWVector(AK::COWVector<unsigned long> const&)
Line
Count
Source
34
59.0M
    COWVector(COWVector const&) = default;
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::COWVector(AK::COWVector<Wasm::GlobalType> const&)
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::COWVector(AK::COWVector<Wasm::FunctionType> const&)
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::COWVector(AK::COWVector<Wasm::TableType> const&)
Unexecuted instantiation: AK::COWVector<Wasm::MemoryType>::COWVector(AK::COWVector<Wasm::MemoryType> const&)
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::COWVector(AK::COWVector<Wasm::ValueType> const&)
Unexecuted instantiation: AK::COWVector<bool>::COWVector(AK::COWVector<bool> const&)
35
239M
    COWVector(COWVector&&) = default;
AK::COWVector<regex::Match>::COWVector(AK::COWVector<regex::Match>&&)
Line
Count
Source
35
79.9M
    COWVector(COWVector&&) = default;
AK::COWVector<AK::Vector<regex::Match, 0ul> >::COWVector(AK::COWVector<AK::Vector<regex::Match, 0ul> >&&)
Line
Count
Source
35
79.9M
    COWVector(COWVector&&) = default;
AK::COWVector<unsigned long>::COWVector(AK::COWVector<unsigned long>&&)
Line
Count
Source
35
79.9M
    COWVector(COWVector&&) = default;
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::COWVector(AK::COWVector<Wasm::FunctionType>&&)
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::COWVector(AK::COWVector<Wasm::TableType>&&)
Unexecuted instantiation: AK::COWVector<Wasm::MemoryType>::COWVector(AK::COWVector<Wasm::MemoryType>&&)
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::COWVector(AK::COWVector<Wasm::GlobalType>&&)
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::COWVector(AK::COWVector<Wasm::ValueType>&&)
Unexecuted instantiation: AK::COWVector<bool>::COWVector(AK::COWVector<bool>&&)
36
37
663
    COWVector& operator=(COWVector const&) = default;
AK::COWVector<regex::Match>::operator=(AK::COWVector<regex::Match> const&)
Line
Count
Source
37
221
    COWVector& operator=(COWVector const&) = default;
AK::COWVector<AK::Vector<regex::Match, 0ul> >::operator=(AK::COWVector<AK::Vector<regex::Match, 0ul> > const&)
Line
Count
Source
37
221
    COWVector& operator=(COWVector const&) = default;
AK::COWVector<unsigned long>::operator=(AK::COWVector<unsigned long> const&)
Line
Count
Source
37
221
    COWVector& operator=(COWVector const&) = default;
38
62.6M
    COWVector& operator=(COWVector&&) = default;
AK::COWVector<regex::Match>::operator=(AK::COWVector<regex::Match>&&)
Line
Count
Source
38
20.8M
    COWVector& operator=(COWVector&&) = default;
AK::COWVector<AK::Vector<regex::Match, 0ul> >::operator=(AK::COWVector<AK::Vector<regex::Match, 0ul> >&&)
Line
Count
Source
38
20.8M
    COWVector& operator=(COWVector&&) = default;
AK::COWVector<unsigned long>::operator=(AK::COWVector<unsigned long>&&)
Line
Count
Source
38
20.8M
    COWVector& operator=(COWVector&&) = default;
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::operator=(AK::COWVector<Wasm::FunctionType>&&)
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::operator=(AK::COWVector<Wasm::TableType>&&)
Unexecuted instantiation: AK::COWVector<Wasm::MemoryType>::operator=(AK::COWVector<Wasm::MemoryType>&&)
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::operator=(AK::COWVector<Wasm::GlobalType>&&)
Unexecuted instantiation: AK::COWVector<bool>::operator=(AK::COWVector<bool>&&)
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::operator=(AK::COWVector<Wasm::ValueType>&&)
39
40
    Vector<T> release() &&
41
66.8M
    {
42
66.8M
        if (m_detail->ref_count() == 1)
43
66.8M
            return exchange(m_detail->m_members, Vector<T>());
44
45
0
        return m_detail->m_members;
46
66.8M
    }
AK::COWVector<regex::Match>::release() &&
Line
Count
Source
41
33.4M
    {
42
33.4M
        if (m_detail->ref_count() == 1)
43
33.4M
            return exchange(m_detail->m_members, Vector<T>());
44
45
0
        return m_detail->m_members;
46
33.4M
    }
AK::COWVector<AK::Vector<regex::Match, 0ul> >::release() &&
Line
Count
Source
41
33.4M
    {
42
33.4M
        if (m_detail->ref_count() == 1)
43
33.4M
            return exchange(m_detail->m_members, Vector<T>());
44
45
0
        return m_detail->m_members;
46
33.4M
    }
47
48
    void append(T const& value)
49
0
    {
50
0
        return append(T { value });
51
0
    }
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::append(Wasm::FunctionType const&)
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::append(Wasm::TableType const&)
Unexecuted instantiation: AK::COWVector<Wasm::MemoryType>::append(Wasm::MemoryType const&)
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::append(Wasm::GlobalType const&)
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::append(Wasm::ValueType const&)
52
53
    void append(T&& value)
54
0
    {
55
0
        copy();
56
0
        m_detail->m_members.append(move(value));
57
0
    }
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::append(Wasm::FunctionType&&)
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::append(Wasm::TableType&&)
Unexecuted instantiation: AK::COWVector<Wasm::MemoryType>::append(Wasm::MemoryType&&)
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::append(Wasm::GlobalType&&)
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::append(Wasm::ValueType&&)
58
59
    void extend(Vector<T>&& values)
60
    {
61
        copy();
62
        m_detail->m_members.extend(move(values));
63
    }
64
65
    void extend(Vector<T> const& values)
66
0
    {
67
0
        copy();
68
0
        m_detail->m_members.extend(values);
69
0
    }
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::extend(AK::Vector<Wasm::FunctionType, 0ul> const&)
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::extend(AK::Vector<Wasm::ValueType, 0ul> const&)
70
71
    void extend(COWVector<T> const& values)
72
    {
73
        copy();
74
        m_detail->m_members.extend(values.m_detail->m_members);
75
    }
76
77
    void resize(size_t size)
78
7.36M
    {
79
7.36M
        copy();
80
7.36M
        m_detail->m_members.resize(size);
81
7.36M
    }
AK::COWVector<unsigned long>::resize(unsigned long)
Line
Count
Source
78
7.36M
    {
79
7.36M
        copy();
80
7.36M
        m_detail->m_members.resize(size);
81
7.36M
    }
Unexecuted instantiation: AK::COWVector<bool>::resize(unsigned long)
82
83
    void ensure_capacity(size_t capacity)
84
4.92M
    {
85
4.92M
        if (m_detail->m_members.capacity() >= capacity)
86
4.92M
            return;
87
88
0
        copy();
89
0
        m_detail->m_members.ensure_capacity(capacity);
90
0
    }
Unexecuted instantiation: AK::COWVector<regex::Match>::ensure_capacity(unsigned long)
AK::COWVector<AK::Vector<regex::Match, 0ul> >::ensure_capacity(unsigned long)
Line
Count
Source
84
4.92M
    {
85
4.92M
        if (m_detail->m_members.capacity() >= capacity)
86
4.92M
            return;
87
88
0
        copy();
89
0
        m_detail->m_members.ensure_capacity(capacity);
90
0
    }
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::ensure_capacity(unsigned long)
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::ensure_capacity(unsigned long)
Unexecuted instantiation: AK::COWVector<Wasm::MemoryType>::ensure_capacity(unsigned long)
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::ensure_capacity(unsigned long)
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::ensure_capacity(unsigned long)
91
92
    void prepend(T value)
93
    {
94
        copy();
95
        m_detail->m_members.prepend(move(value));
96
    }
97
98
    template<typename... Args>
99
    void empend(Args&&... args)
100
5.93M
    {
101
5.93M
        copy();
102
5.93M
        m_detail->m_members.empend(forward<Args>(args)...);
103
5.93M
    }
void AK::COWVector<regex::Match>::empend<>()
Line
Count
Source
100
1.01M
    {
101
1.01M
        copy();
102
1.01M
        m_detail->m_members.empend(forward<Args>(args)...);
103
1.01M
    }
void AK::COWVector<AK::Vector<regex::Match, 0ul> >::empend<>()
Line
Count
Source
100
4.92M
    {
101
4.92M
        copy();
102
4.92M
        m_detail->m_members.empend(forward<Args>(args)...);
103
4.92M
    }
104
105
    void clear()
106
4.82M
    {
107
4.82M
        if (m_detail->ref_count() > 1)
108
0
            m_detail = make_ref_counted<Detail>();
109
4.82M
        else
110
4.82M
            m_detail->m_members.clear();
111
4.82M
    }
112
113
    T& mutable_at(size_t index)
114
69.5M
    {
115
        // We're handing out a mutable reference, so make sure we own the data exclusively.
116
69.5M
        copy();
117
69.5M
        return m_detail->m_members.at(index);
118
69.5M
    }
AK::COWVector<regex::Match>::mutable_at(unsigned long)
Line
Count
Source
114
1.01M
    {
115
        // We're handing out a mutable reference, so make sure we own the data exclusively.
116
1.01M
        copy();
117
1.01M
        return m_detail->m_members.at(index);
118
1.01M
    }
AK::COWVector<AK::Vector<regex::Match, 0ul> >::mutable_at(unsigned long)
Line
Count
Source
114
61.0M
    {
115
        // We're handing out a mutable reference, so make sure we own the data exclusively.
116
61.0M
        copy();
117
61.0M
        return m_detail->m_members.at(index);
118
61.0M
    }
AK::COWVector<unsigned long>::mutable_at(unsigned long)
Line
Count
Source
114
7.50M
    {
115
        // We're handing out a mutable reference, so make sure we own the data exclusively.
116
7.50M
        copy();
117
7.50M
        return m_detail->m_members.at(index);
118
7.50M
    }
119
120
    T const& at(size_t index) const
121
46.4M
    {
122
46.4M
        return m_detail->m_members.at(index);
123
46.4M
    }
Unexecuted instantiation: AK::COWVector<unsigned long>::at(unsigned long) const
AK::COWVector<AK::Vector<regex::Match, 0ul> >::at(unsigned long) const
Line
Count
Source
121
46.4M
    {
122
46.4M
        return m_detail->m_members.at(index);
123
46.4M
    }
124
125
    T const& operator[](size_t index) const
126
0
    {
127
0
        return m_detail->m_members[index];
128
0
    }
Unexecuted instantiation: AK::COWVector<AK::Vector<regex::Match, 0ul> >::operator[](unsigned long) const
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::operator[](unsigned long) const
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::operator[](unsigned long) const
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::operator[](unsigned long) const
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::operator[](unsigned long) const
129
130
    size_t capacity() const
131
4.92M
    {
132
4.92M
        return m_detail->m_members.capacity();
133
4.92M
    }
134
135
    size_t size() const
136
32.7M
    {
137
32.7M
        return m_detail->m_members.size();
138
32.7M
    }
AK::COWVector<unsigned long>::size() const
Line
Count
Source
136
7.50M
    {
137
7.50M
        return m_detail->m_members.size();
138
7.50M
    }
AK::COWVector<regex::Match>::size() const
Line
Count
Source
136
1.01M
    {
137
1.01M
        return m_detail->m_members.size();
138
1.01M
    }
AK::COWVector<AK::Vector<regex::Match, 0ul> >::size() const
Line
Count
Source
136
24.2M
    {
137
24.2M
        return m_detail->m_members.size();
138
24.2M
    }
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::size() const
Unexecuted instantiation: AK::COWVector<Wasm::MemoryType>::size() const
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::size() const
Unexecuted instantiation: AK::COWVector<bool>::size() const
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::size() const
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::size() const
139
140
    bool is_empty() const
141
    {
142
        return m_detail->m_members.is_empty();
143
    }
144
145
    T const& first() const
146
    {
147
        return m_detail->m_members.first();
148
    }
149
150
    T const& last() const
151
    {
152
        return m_detail->m_members.last();
153
    }
154
155
private:
156
    void copy()
157
82.8M
    {
158
82.8M
        if (m_detail->ref_count() <= 1)
159
73.1M
            return;
160
9.73M
        auto new_detail = make_ref_counted<Detail>();
161
9.73M
        new_detail->m_members = m_detail->m_members;
162
9.73M
        m_detail = new_detail;
163
9.73M
    }
AK::COWVector<regex::Match>::copy()
Line
Count
Source
157
2.03M
    {
158
2.03M
        if (m_detail->ref_count() <= 1)
159
2.03M
            return;
160
0
        auto new_detail = make_ref_counted<Detail>();
161
0
        new_detail->m_members = m_detail->m_members;
162
0
        m_detail = new_detail;
163
0
    }
AK::COWVector<AK::Vector<regex::Match, 0ul> >::copy()
Line
Count
Source
157
65.9M
    {
158
65.9M
        if (m_detail->ref_count() <= 1)
159
57.7M
            return;
160
8.16M
        auto new_detail = make_ref_counted<Detail>();
161
8.16M
        new_detail->m_members = m_detail->m_members;
162
8.16M
        m_detail = new_detail;
163
8.16M
    }
AK::COWVector<unsigned long>::copy()
Line
Count
Source
157
14.8M
    {
158
14.8M
        if (m_detail->ref_count() <= 1)
159
13.3M
            return;
160
1.57M
        auto new_detail = make_ref_counted<Detail>();
161
1.57M
        new_detail->m_members = m_detail->m_members;
162
1.57M
        m_detail = new_detail;
163
1.57M
    }
Unexecuted instantiation: AK::COWVector<Wasm::FunctionType>::copy()
Unexecuted instantiation: AK::COWVector<Wasm::TableType>::copy()
Unexecuted instantiation: AK::COWVector<Wasm::MemoryType>::copy()
Unexecuted instantiation: AK::COWVector<Wasm::GlobalType>::copy()
Unexecuted instantiation: AK::COWVector<Wasm::ValueType>::copy()
Unexecuted instantiation: AK::COWVector<bool>::copy()
164
165
    NonnullRefPtr<Detail> m_detail;
166
};
167
168
}
169
170
#if USING_AK_GLOBALLY
171
using AK::COWVector;
172
#endif