Line data Source code
1 : #pragma once
2 :
3 : #include <functional>
4 : #include <iostream>
5 : #include <optional>
6 : #include <ostream>
7 : #include <string>
8 :
9 : namespace containers {
10 :
11 : template <typename T>
12 : class vector {
13 : public:
14 20 : vector() = default;
15 :
16 3 : vector(const vector<T>& other) {
17 3 : CreateNewDataContainer(other);
18 3 : CopyData(other.m_data, m_data);
19 3 : }
20 :
21 : vector(vector<T>&& other) {
22 : m_data = other.m_data;
23 : other.m_data = nullptr;
24 :
25 : m_size = other.m_size;
26 : m_capacity = other.m_capacity;
27 : }
28 :
29 35 : vector(const std::initializer_list<T>& args) {
30 35 : m_capacity = args.size();
31 35 : m_data = new T[m_capacity];
32 :
33 135 : for (const auto& arg : args) {
34 100 : push_back(arg);
35 : }
36 35 : }
37 :
38 3 : vector<T>& operator=(const vector<T>& other) {
39 3 : CreateNewDataContainer(other);
40 3 : CopyData(other.m_data, m_data);
41 :
42 3 : return *this;
43 : }
44 :
45 60 : ~vector() { delete[] m_data; }
46 :
47 13 : friend bool operator==(const vector<T>& lhs, const vector<T>& rhs) {
48 13 : const auto size = lhs.size();
49 13 : if (size != rhs.size()) {
50 0 : return false;
51 : }
52 :
53 62 : for (size_t i = 0; i < size; ++i) {
54 49 : if (lhs[i] != rhs[i]) {
55 0 : return false;
56 : }
57 : }
58 :
59 13 : return true;
60 : }
61 :
62 : friend bool operator!=(const vector<T>& lhs, const vector<T>& rhs) {
63 : return not(lhs == rhs);
64 : }
65 :
66 107 : T& operator[](size_t index) const { return m_data[index]; }
67 :
68 7 : T& at(size_t index) const {
69 7 : if (index >= m_size or not m_data) {
70 4 : throw std::out_of_range("Trying access data out of range");
71 : }
72 :
73 3 : return m_data[index];
74 : }
75 :
76 0 : friend std::ostream& operator<<(std::ostream& os, const vector<T>& other) {
77 0 : for (size_t i = 0; i < other.m_size; ++i) {
78 0 : os << other.m_data[i] << " ";
79 : }
80 0 : os << std::endl;
81 :
82 0 : return os;
83 : }
84 :
85 116 : void push_back(const T& value) {
86 116 : if (not m_data) {
87 2 : m_data = new T[m_capacity];
88 : }
89 :
90 116 : if (m_size == m_capacity) {
91 3 : m_capacity = m_capacity * 10;
92 3 : T* temp = new T[m_capacity];
93 :
94 3 : CopyData(temp, m_data);
95 :
96 3 : delete[] m_data;
97 3 : m_data = temp;
98 : }
99 :
100 116 : m_data[m_size] = value;
101 116 : m_size++;
102 116 : }
103 :
104 2 : void emplace_back(const T&& value) {
105 2 : if (not m_data) {
106 1 : m_data = new T[m_capacity];
107 : }
108 :
109 2 : if (m_size == m_capacity) {
110 1 : m_capacity = m_capacity * 10;
111 1 : T* temp = new T[m_capacity];
112 :
113 1 : CopyData(temp, m_data);
114 :
115 1 : delete[] m_data;
116 1 : m_data = temp;
117 : }
118 :
119 2 : m_data[m_size] = std::move(value);
120 2 : m_size++;
121 2 : }
122 :
123 2 : void pop_back() {
124 2 : if (m_data) {
125 1 : m_size--;
126 : }
127 2 : }
128 :
129 51 : size_t size() const { return m_size; }
130 :
131 9 : size_t capacity() const { return m_capacity; }
132 :
133 11 : bool empty() const { return m_size == 0; }
134 :
135 2 : T* begin() const { return m_data; }
136 :
137 2 : std::optional<std::reference_wrapper<T>> front() const {
138 2 : if (not m_data or m_size == 0) {
139 1 : return std::nullopt;
140 : }
141 :
142 1 : return m_data[0];
143 : }
144 :
145 2 : T* end() const {
146 2 : if (not m_data) {
147 1 : return nullptr;
148 : }
149 :
150 1 : return m_data + m_size;
151 : }
152 :
153 2 : std::optional<std::reference_wrapper<T>> back() const {
154 2 : if (not m_data or m_size == 0) {
155 1 : return std::nullopt;
156 : }
157 :
158 1 : return m_data[m_size - 1];
159 : }
160 :
161 2 : void shrink_to_fit() {
162 2 : m_capacity = m_size;
163 2 : T* temp = new T[m_size];
164 4 : for (size_t i = 0; i < m_size; ++i) {
165 2 : temp[i] = m_data[i];
166 : }
167 2 : delete[] m_data;
168 2 : m_data = temp;
169 2 : }
170 :
171 2 : void clear() {
172 2 : if (not m_data) {
173 1 : return;
174 : }
175 :
176 1 : m_size = 0;
177 1 : m_capacity = 10;
178 :
179 1 : delete[] m_data;
180 1 : m_data = new T[m_capacity];
181 : }
182 :
183 2 : void reverse() {
184 2 : if (not m_data) {
185 1 : return;
186 : }
187 :
188 2 : for (size_t i = 0; i < m_size / 2; ++i) {
189 1 : const auto last = m_size - 1 - i;
190 1 : T temp = m_data[i];
191 1 : m_data[i] = m_data[last];
192 1 : m_data[last] = temp;
193 : }
194 : }
195 :
196 2 : void assing(size_t count, const T& value) {
197 2 : if (m_data) {
198 1 : delete[] m_data;
199 : }
200 :
201 2 : m_data = new T[count];
202 2 : m_capacity = count;
203 2 : m_size = count;
204 :
205 16 : for (size_t i = 0; i < m_capacity; ++i) {
206 14 : m_data[i] = value;
207 : }
208 2 : }
209 :
210 4 : void swap(vector<T>& other) {
211 4 : T* temp = m_data;
212 4 : const size_t size = m_size;
213 4 : const size_t capacity = m_capacity;
214 :
215 4 : m_data = other.m_data;
216 4 : m_size = other.m_size;
217 4 : m_capacity = other.m_capacity;
218 :
219 4 : other.m_data = temp;
220 4 : other.m_size = size;
221 4 : other.m_capacity = capacity;
222 4 : }
223 :
224 2 : void resize(size_t count) {
225 2 : T* temp = new T[count];
226 12 : for (size_t i = 0; i < count; ++i) {
227 10 : if (i >= m_size) {
228 8 : temp[i] = 0;
229 : } else {
230 2 : temp[i] = m_data[i];
231 : }
232 10 : std::cout << std::endl;
233 : }
234 :
235 2 : m_capacity = m_size = count;
236 2 : delete[] m_data;
237 2 : m_data = temp;
238 2 : }
239 :
240 2 : void resize(size_t count, const T& value) {
241 2 : T* temp = new T[count];
242 12 : for (size_t i = 0; i < count; ++i) {
243 10 : if (i >= m_size) {
244 8 : temp[i] = value;
245 : } else {
246 2 : temp[i] = m_data[i];
247 : }
248 10 : std::cout << std::endl;
249 : }
250 :
251 2 : m_capacity = m_size = count;
252 2 : delete[] m_data;
253 2 : m_data = temp;
254 2 : }
255 :
256 : private:
257 10 : void CopyData(const T* src, T* dest) {
258 51 : for (size_t i = 0; i < m_size; ++i) {
259 41 : dest[i] = src[i];
260 : }
261 10 : }
262 :
263 6 : void CreateNewDataContainer(const vector<T>& other) {
264 6 : m_size = other.m_size;
265 6 : m_capacity = other.m_capacity;
266 :
267 6 : if (m_data) {
268 2 : delete[] m_data;
269 : }
270 6 : m_data = new T[m_capacity];
271 6 : }
272 :
273 : size_t m_size{};
274 : size_t m_capacity{10};
275 : T* m_data = nullptr;
276 : };
277 :
278 : } // namespace containers
|