MOS Source Code
Loading...
Searching...
No Matches
vector.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
5#include <algorithm>
6#include <cstddef>
8#include <mos_stdlib.hpp>
9
10namespace mos
11{
12 template<typename TItem>
13 class vector
14 {
15 static_assert(!std::is_void_v<TItem>, "doesn't make sense");
16
17 public:
18 vector() = default;
19 vector(std::initializer_list<TItem> list)
20 {
21 reserve(list.size());
22 for (const auto &item : list)
23 {
24 new (&at(m_size)) TItem(item);
25 ++m_size;
26 }
27 }
28
29 vector(const vector &other)
30 {
31 *this = other;
32 }
33
34 vector &operator=(const vector &other)
35 {
36 if (this != &other)
37 {
38 clear();
39 for (size_t i = 0; i < other.m_size; ++i)
40 push_back(other.at(i));
41 }
42 return *this;
43 }
44
45 vector(vector &&other) noexcept : m_storage(other.m_storage), m_size(other.m_size), m_capacity(other.m_capacity)
46 {
47 other.m_storage = nullptr;
48 other.m_size = 0;
49 other.m_capacity = 0;
50 }
51
52 vector &operator=(vector &&other) noexcept
53 {
54 if (this != &other)
55 {
56 clear();
57 m_storage = other.m_storage;
58 m_size = other.m_size;
59 m_capacity = other.m_capacity;
60
61 other.m_storage = nullptr;
62 other.m_size = 0;
63 other.m_capacity = 0;
64 }
65 return *this;
66 }
67
68 ~vector() noexcept
69 {
70 clear();
71 }
72
73 private:
74 void *m_storage = nullptr;
75 size_t m_size = 0;
76 size_t m_capacity = 0;
77
78 public:
79 auto &operator[](size_t index) const noexcept
80 {
81 return at(index);
82 }
83
84 auto &at(this auto &Self, size_t index) noexcept
85 {
86 const auto storage_item = reinterpret_cast<TItem *>(Self.m_storage);
87 return storage_item[index];
88 }
89
90 auto data(this auto &Self) noexcept
91 {
92 if constexpr (std::is_const_v<decltype(Self)>)
93 return reinterpret_cast<const TItem *>(Self.m_storage);
94 else
95 return reinterpret_cast<TItem *>(Self.m_storage);
96 }
97
98 auto size() const noexcept
99 {
100 return m_size;
101 }
102
103 auto capacity() const noexcept
104 {
105 return m_capacity;
106 }
107
108 auto empty() const noexcept
109 {
110 return m_size == 0;
111 }
112
113 auto reserve(size_t newSize) noexcept
114 {
115 newSize = GetNewCapacityForSize(newSize);
116 if (newSize > m_capacity)
117 {
118 TItem *newStorage = reinterpret_cast<TItem *>(kcalloc<char>(newSize * sizeof(TItem)));
119
120 for (size_t i = 0; i < m_size; ++i)
121 newStorage[i] = std::move(at(i));
122
123 kfree(m_storage);
124 m_storage = newStorage;
125 m_capacity = newSize;
126 }
127 }
128
129 auto resize(size_t new_size) noexcept
130 {
131 if (new_size > m_capacity)
132 reserve(new_size);
133
134 for (size_t i = m_size; i < new_size; ++i)
135 new (std::addressof(at(m_size))) TItem();
136
137 for (size_t i = new_size; i < m_size; ++i)
138 at(i).~TItem();
139
140 m_size = new_size;
141 }
142
143 auto push_back(const TItem &value) noexcept
144 {
145 if (m_size == m_capacity)
146 reserve(m_capacity + 1);
147 new (std::addressof(at(m_size))) TItem(value);
148 ++m_size;
149 }
150
151 auto push_back(TItem &&value) noexcept
152 {
153 if (m_size == m_capacity)
154 reserve(m_capacity + 1);
155 new (std::addressof(at(m_size))) TItem(std::move(value));
156 ++m_size;
157 }
158
159 auto pop_back() noexcept
160 {
161 if (m_size > 0)
162 {
163 --m_size;
164 at(m_size).~TItem();
165 }
166 }
167
168 auto clear() noexcept
169 {
170 if (m_storage && m_size)
171 {
172 while (!empty())
173 pop_back();
174
175 kfree(m_storage);
176 m_size = 0;
177 m_storage = nullptr;
178 m_capacity = 0;
179 }
180 }
181
182 private:
183 static constexpr size_t GetNewCapacityForSize(size_t newSize) noexcept
184 {
185 size_t cap = 1;
186 while (cap < newSize)
187 cap *= 2;
188 return cap;
189 }
190
191 private:
192 template<typename TPointer, typename TReference>
194 {
195 private:
196 TPointer m_storage;
197 size_t m_index;
198
199 public:
200 explicit base_iterator(void *storage, size_t index) noexcept : m_storage(reinterpret_cast<TPointer>(storage)), m_index(index) {};
201
202 bool operator!=(const base_iterator &other) const noexcept
203 {
204 return m_index != other.m_index;
205 }
206
208 {
209 ++m_index;
210 return *this;
211 }
212
213 TReference operator*() const noexcept
214 {
215 return m_storage[m_index];
216 }
217 };
218
219 private:
222
223 public:
224 auto begin() noexcept
225 {
226 return iterator(m_storage, 0);
227 }
228
229 auto end() noexcept
230 {
231 return iterator(m_storage, m_size);
232 }
233
234 auto begin() const noexcept
235 {
236 return const_iterator(m_storage, 0);
237 }
238
239 auto end() const noexcept
240 {
242 }
243 };
244} // namespace mos
base_iterator(void *storage, size_t index) noexcept
Definition vector.hpp:200
TReference operator*() const noexcept
Definition vector.hpp:213
base_iterator & operator++() noexcept
Definition vector.hpp:207
bool operator!=(const base_iterator &other) const noexcept
Definition vector.hpp:202
size_t m_size
Definition vector.hpp:75
auto end() const noexcept
Definition vector.hpp:239
vector & operator=(vector &&other) noexcept
Definition vector.hpp:52
auto size() const noexcept
Definition vector.hpp:98
auto & operator[](size_t index) const noexcept
Definition vector.hpp:79
auto capacity() const noexcept
Definition vector.hpp:103
void * m_storage
Definition vector.hpp:74
auto begin() noexcept
Definition vector.hpp:224
auto resize(size_t new_size) noexcept
Definition vector.hpp:129
size_t m_capacity
Definition vector.hpp:76
auto pop_back() noexcept
Definition vector.hpp:159
vector(std::initializer_list< TItem > list)
Definition vector.hpp:19
auto data(this auto &Self) noexcept
Definition vector.hpp:90
vector(const vector &other)
Definition vector.hpp:29
auto & at(this auto &Self, size_t index) noexcept
Definition vector.hpp:84
auto begin() const noexcept
Definition vector.hpp:234
auto end() noexcept
Definition vector.hpp:229
auto clear() noexcept
Definition vector.hpp:168
vector & operator=(const vector &other)
Definition vector.hpp:34
base_iterator< TItem *, TItem & > iterator
Definition vector.hpp:220
static constexpr size_t GetNewCapacityForSize(size_t newSize) noexcept
Definition vector.hpp:183
auto push_back(const TItem &value) noexcept
Definition vector.hpp:143
base_iterator< const TItem *, const TItem & > const_iterator
Definition vector.hpp:221
auto push_back(TItem &&value) noexcept
Definition vector.hpp:151
vector()=default
~vector() noexcept
Definition vector.hpp:68
auto empty() const noexcept
Definition vector.hpp:108
auto reserve(size_t newSize) noexcept
Definition vector.hpp:113
vector(vector &&other) noexcept
Definition vector.hpp:45