FMI Table
| Kamen Mladenov | FMI Computer Science Year 1 Group 6 | Project 2 | Project Topic 7 |
List.hpp
Go to the documentation of this file.
1#ifndef HEADER_LIST
2#define HEADER_LIST
3
8#include <istream>
9#include <ostream>
10
21template <typename T>
22class List {
23protected:
24 T* elements;
25 unsigned length;
26 unsigned count;
27
28 void resize();
29 void free();
30 void copyFrom(const List& other);
31
32public:
34 List(const T* elements, unsigned elementsCount);
36 List(unsigned length);
38 void add(const T& element);
40 void insertAt(const T& element, unsigned index);
42 bool removeAt(unsigned index);
44 unsigned findIndex(const T& element) const;
45 bool contain(const T& element) const;
47 T& operator[](unsigned index);
49 const T& operator[](unsigned index) const;
51 const T* raw_data() const;
53 void clear();
54
56 List<T>& operator+=(const List<T> other);
57
59 std::istream& read(std::istream& istr);
61 std::ostream& write(std::ostream& ostr) const;
62
64 unsigned get_length() const;
66 unsigned get_count() const;
67
68 List();
69 List& operator=(const List& other);
70 List(const List& other);
71 ~List();
72
73 List(List&& other);
74 List& operator=(List&& other);
75};
76
78template <typename T>
79std::istream& operator>>(std::istream& istr, List<T>& obj);
81template <typename T>
82std::ostream& operator<<(std::ostream& ostr, const List<T>& obj);
83
84/* Private */
85
86template <typename T>
87void List<T>::resize() {
88 length = (length == 0) ? 8 : length << 1;
89 T* temp = new T[length];
90 for (int i = 0; i < count; i++)
91 temp[i] = elements[i];
92 delete[] elements;
93 elements = temp;
94}
95
96template <typename T>
97void List<T>::free() {
98 delete[] elements;
99}
100
101template <typename T>
102void List<T>::copyFrom(const List& other) {
103 elements = new T[other.length];
104 for (int i = 0; i < other.count; i++)
105 elements[i] = other.elements[i];
106 length = other.length;
107 count = other.count;
108}
109
110/* Public */
111
112template <typename T>
113List<T>::List(const T* elements, unsigned elementsCount) {
114 length = 8;
115 count = elementsCount;
116 this->elements = new T[length];
117 for (unsigned i = 0; i < count; i++)
118 this->elements[i] = elements[i];
119}
120
121template <typename T>
122List<T>::List(unsigned length) {
123 this->length = count = length;
124 this->elements = new T[length];
125 for (unsigned i = 0; i < count; i++)
126 this->elements[i] = elements[i];
127}
128
132template <typename T>
133void List<T>::add(const T& element) {
134 if (length == count) resize();
135
136 elements[count++] = element;
137}
138
145template <typename T>
146void List<T>::insertAt(const T& element, unsigned index) {
147 if (index >= count) {
148 add(element);
149 return;
150 }
151 if (length == count) resize();
152
153 for (unsigned i = count; i > index; i--)
154 elements[i] = elements[i - 1];
155
156 elements[index] = element;
157 count++;
158}
159
165template <typename T>
166bool List<T>::removeAt(unsigned index) {
167 if (index >= count) return false;
168
169 for (int i = index; i < count; i++)
170 elements[i] = elements[i + 1];
171 count--;
172 return true;
173}
174
180template <typename T>
181unsigned List<T>::findIndex(const T& element) const {
182 unsigned ind = 0;
183 while (ind < count && elements[ind].compare(element) != 0)
184 ind++;
185 return ind;
186}
187
193template <typename T>
194bool List<T>::contain(const T& element) const {
195 return findIndex(element) < count;
196}
197
198template <typename T>
199T& List<T>::operator[](unsigned index) {
200 return elements[index];
201}
202
203template <typename T>
204const T& List<T>::operator[](unsigned index) const {
205 return elements[index];
206}
207
208template <typename T>
209const T* List<T>::raw_data() const {
210 return elements;
211}
212
213template <typename T>
215 free();
216 length = 8;
217 count = 0;
218 this->elements = new T[length];
219}
220
221template <typename T>
223 for (unsigned i = 0; i < other.length; i++)
224 add(other[i]);
225 return *this;
226}
227
237template <typename T>
238std::istream& List<T>::read(std::istream& istr) {
239 istr.read((char*)&length, sizeof(length));
240 istr.read((char*)&count, sizeof(count));
241
242 delete[] elements;
243 elements = new T[length];
244
245 for (int i = 0; i < count; i++)
246 elements[i].read(istr);
247
248 return istr;
249}
250
259template <typename T>
260std::ostream& List<T>::write(std::ostream& ostr) const {
261 ostr.write((const char*)&length, sizeof(length));
262 ostr.write((const char*)&count, sizeof(count));
263
264 for (int i = 0; i < count; i++)
265 elements[i].write(ostr);
266
267 return ostr;
268}
269
273template <typename T>
274unsigned List<T>::get_length() const {
275 return length;
276}
277
281template <typename T>
282unsigned List<T>::get_count() const {
283 return count;
284}
285
286// Rule of 4
287
288template <typename T>
289List<T>::List() : List(nullptr, 0) {}
290
291template <typename T>
292List<T>& List<T>::operator=(const List& other) {
293 if (this != &other) {
294 free();
295 copyFrom(other);
296 }
297 return *this;
298}
299
300template <typename T>
301List<T>::List(const List& other) {
302 copyFrom(other);
303}
304
305template <typename T>
307 free();
308}
309
310// Move semantics
311
312template <typename T>
313List<T>::List(List&& other) {
314 length = other.length;
315 count = other.count;
316 elements = other.elements;
317 other.elements = nullptr;
318}
319
320template <typename T>
322 if (this != &other) {
323 free();
324 length = other.length;
325 count = other.count;
326 elements = other.elements;
327 other.elements = nullptr;
328 }
329 return *this;
330}
331
332/* Outside of class */
333
341template <typename T>
342std::istream& operator>>(std::istream& istr, List<T>& obj) {
343 List<T> newObj;
344 unsigned count;
345 istr >> count;
346
347 T temp;
348 for (int i = 0; i < count; i++) {
349 istr >> temp;
350 obj.add(temp);
351 }
352
353 return istr;
354}
355
362template <typename T>
363std::ostream& operator<<(std::ostream& ostr, const List<T>& obj) {
364 ostr << obj.get_count() << std::endl;
365 for (int i = 0; i < obj.get_count(); i++)
366 ostr << obj[i];
367
368 return ostr;
369}
370
371
372#endif
std::istream & operator>>(std::istream &istr, List< T > &obj)
Reads List from stream with >> operator.
Definition: List.hpp:342
std::ostream & operator<<(std::ostream &ostr, const List< T > &obj)
Writes List to stream with << operator.
Definition: List.hpp:363
void read(T *storage)
Reads user input and stores it.
Definition: Toolbox.hpp:26
Templated class that stores an array of elements in dynamic memory.
Definition: List.hpp:22
bool contain(const T &element) const
Definition: List.hpp:194
const T * raw_data() const
Returns raw array of data.
Definition: List.hpp:209
T & operator[](unsigned index)
Returns reference to element at index.
Definition: List.hpp:199
unsigned findIndex(const T &element) const
Finds the index of element.
Definition: List.hpp:181
unsigned get_count() const
Returns the count.
Definition: List.hpp:282
List(unsigned length)
Allocates memory for the given length.
Definition: List.hpp:122
std::istream & read(std::istream &istr)
Reads from stream.
Definition: List.hpp:238
const T & operator[](unsigned index) const
Returns constant reference to element at index.
Definition: List.hpp:204
std::ostream & write(std::ostream &ostr) const
Writes to stream.
Definition: List.hpp:260
List(const T *elements, unsigned elementsCount)
Copies all elements in given array.
Definition: List.hpp:113
unsigned get_length() const
Returns the length.
Definition: List.hpp:274
List< T > & operator+=(const List< T > other)
Appends elements from other list.
Definition: List.hpp:222
void add(const T &element)
Adds an element.
Definition: List.hpp:133
bool removeAt(unsigned index)
Removes element at index.
Definition: List.hpp:166
void clear()
Removes all data.
Definition: List.hpp:214
void insertAt(const T &element, unsigned index)
Inserts element at given index.
Definition: List.hpp:146