aboutsummaryrefslogtreecommitdiff
path: root/week11/Exercise07
diff options
context:
space:
mode:
Diffstat (limited to 'week11/Exercise07')
-rw-r--r--week11/Exercise07/DynamicArray.hpp90
-rw-r--r--week11/Exercise07/Numbers.cpp44
-rw-r--r--week11/Exercise07/Numbers.h14
-rw-r--r--week11/Exercise07/String.cpp49
-rw-r--r--week11/Exercise07/String.h13
5 files changed, 210 insertions, 0 deletions
diff --git a/week11/Exercise07/DynamicArray.hpp b/week11/Exercise07/DynamicArray.hpp
new file mode 100644
index 0000000..b7d8fb7
--- /dev/null
+++ b/week11/Exercise07/DynamicArray.hpp
@@ -0,0 +1,90 @@
+#pragma once
+
+template <class T>
+class DynamicArray {
+ void free();
+ void copyFrom(const DynamicArray& other);
+
+protected:
+ T* elems;
+ unsigned allocated;
+ unsigned size;
+
+public:
+ DynamicArray();
+ virtual ~DynamicArray();
+ DynamicArray(const DynamicArray& other);
+ DynamicArray& operator=(const DynamicArray& other);
+ DynamicArray(DynamicArray&& other);
+ DynamicArray& operator=(DynamicArray&& other);
+
+ virtual T& operator[](int index) = 0;
+ virtual const T& operator[](int index) const = 0;
+ // Отговорът е не, не можем да използваме оператор += в полморфна йерархия
+ // Понеже String и Numbers не са шаблонни, а използват конкретна "инстанция" на шаблонния клас
+ // тогава полиморфно += би означавало += между разногласни типове, което няма как да стане (добре).
+ virtual DynamicArray& operator+=(const DynamicArray& other) = 0;
+};
+
+template <class T>
+void DynamicArray<T>::free() {
+ delete[] elems;
+}
+
+template <class T>
+void DynamicArray<T>::copyFrom(const DynamicArray& other) {
+ this->size = other.size;
+ this->allocated = other.allocated;
+ elems = new T[allocated];
+ for (int i = 0; i < size; i++) {
+ elems[i] = other.elems[i];
+ }
+}
+
+template <class T>
+DynamicArray<T>::DynamicArray() {
+ elems = nullptr;
+ size = allocated = 0;
+}
+
+template <class T>
+DynamicArray<T>::~DynamicArray() {
+ free();
+}
+
+template <class T>
+DynamicArray<T>::DynamicArray(const DynamicArray& other) {
+ copyFrom(other);
+}
+
+template <class T>
+DynamicArray<T>& DynamicArray<T>::operator=(const DynamicArray& other) {
+ if (this != &other) {
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+template <class T>
+DynamicArray<T>::DynamicArray(DynamicArray&& other) {
+ this->elems = other.elems;
+ other.elems = nullptr;
+ this->second = other.second;
+ other.second = nullptr;
+ this->allocated = other.allocated;
+ this->size = other.size;
+}
+
+template <class T>
+DynamicArray<T>& DynamicArray<T>::operator=(DynamicArray&& other) {
+ if (this != &other) {
+ free();
+
+ this->elems = other.elems;
+ other.elems = nullptr;
+ this->allocated = other.allocated;
+ this->size = other.size;
+ }
+ return *this;
+}
diff --git a/week11/Exercise07/Numbers.cpp b/week11/Exercise07/Numbers.cpp
new file mode 100644
index 0000000..db8f218
--- /dev/null
+++ b/week11/Exercise07/Numbers.cpp
@@ -0,0 +1,44 @@
+#include "Numbers.h"
+#include "DynamicArray.hpp"
+
+int& Numbers::operator[](int index) {
+ if (index >= size) throw "Index out of bounds";
+
+ for (int i = 0; i < size; i++) {
+ if (elems[i] < index) {
+ return elems[i];
+ }
+ }
+ return elems[0];
+}
+
+const int& Numbers::operator[](int index) const {
+ if (index >= size) throw "Index out of bounds";
+
+ for (int i = 0; i < size; i++) {
+ if (elems[i] < index) {
+ return elems[i];
+ }
+ }
+ return elems[0];
+}
+
+Numbers& Numbers::operator+=(const Numbers& other) {
+ int* biggerElems = new int[other.allocated + allocated];
+ for (int i = 0; i < other.size; i++) {
+ biggerElems[i] = other.elems[i];
+ }
+ for (int i = 0; i < size; i++) {
+ biggerElems[other.size + i] = elems[i];
+ }
+ delete[] elems;
+ elems = biggerElems;
+ size += other.size;
+ allocated += other.allocated;
+
+ return *this;
+}
+
+DynamicArray<int>& Numbers::operator+=(const DynamicArray<int>& other) {
+ return *this += (const Numbers&)other;
+}
diff --git a/week11/Exercise07/Numbers.h b/week11/Exercise07/Numbers.h
new file mode 100644
index 0000000..1219ab0
--- /dev/null
+++ b/week11/Exercise07/Numbers.h
@@ -0,0 +1,14 @@
+#pragma once
+#include "DynamicArray.hpp"
+
+class Numbers : DynamicArray<int> {
+ // Не можем да имаме полиморфно += (виж DynamicArray.hpp), но пак трябва да го имплементираме
+ // по някакъв начин.
+ virtual DynamicArray& operator+=(const DynamicArray& other) override;
+
+public:
+ virtual int& operator[](int index) override;
+ virtual const int& operator[](int index) const override;
+ Numbers& operator+=(const Numbers& other);
+};
+
diff --git a/week11/Exercise07/String.cpp b/week11/Exercise07/String.cpp
new file mode 100644
index 0000000..8406f3c
--- /dev/null
+++ b/week11/Exercise07/String.cpp
@@ -0,0 +1,49 @@
+#include "String.h"
+#include <cstring>
+
+char& String::operator[](int index) {
+ if (index <= 1) throw "Invalid index";
+
+ for (int i = 0; i < size; i++) {
+ if ('A' <= elems[i] && elems[i] <= 'Z') {
+ index--;
+ if (index == 0) {
+ return elems[i];
+ }
+ }
+ }
+ return elems[size-1];
+}
+
+const char& String::operator[](int index) const {
+ if (index <= 1) throw "Invalid index";
+
+ for (int i = 0; i < size; i++) {
+ if ('A' <= elems[i] && elems[i] <= 'Z') {
+ index--;
+ if (index == 0) {
+ return elems[i];
+ }
+ }
+ }
+ return elems[size-1];
+}
+
+String& String::operator+=(const String& other) {
+ char* biggerStr = new char[allocated + other.allocated];
+ for (int i = 0; i < size; i++) {
+ biggerStr[i] = elems[i];
+ }
+ for (int i = 0; i < other.size; i++) {
+ biggerStr[size + i] = other.elems[i];
+ }
+ delete[] elems;
+ elems = biggerStr;
+ allocated += other.allocated;
+ size += other.size;
+ return *this;
+}
+
+DynamicArray<char>& String::operator+=(const DynamicArray<char>& other) {
+ return *this += (const String&)other;
+}
diff --git a/week11/Exercise07/String.h b/week11/Exercise07/String.h
new file mode 100644
index 0000000..d34555a
--- /dev/null
+++ b/week11/Exercise07/String.h
@@ -0,0 +1,13 @@
+#pragma once
+#include "DynamicArray.hpp"
+
+class String : DynamicArray<char> {
+ // Не можем да имаме полиморфно += (виж DynamicArray.hpp), но пак трябва да го имплементираме
+ // по някакъв начин.
+ virtual DynamicArray& operator+=(const DynamicArray& other) override;
+
+public:
+ virtual char& operator[](int index) override;
+ virtual const char& operator[](int index) const override;
+ String& operator+=(const String& other);
+};