/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 |