#pragma once template class Set { T* elements; unsigned size; void free(); void copyFrom(const Set& other); public: Set(); ~Set(); Set(const Set& other); Set& operator=(const Set& other); Set(Set&& other); Set& operator=(Set&& other); Set& operator+=(const Set& right); template friend Set operator+(const Set& left, const Set& right); Set& operator*=(const Set& right); template friend Set operator*(const Set& left, const Set& right); Set& operator-=(const Set& right); template friend Set operator-(const Set& left, const Set& right); }; template void Set::free() { delete[] elements; } template void Set::copyFrom(const Set& other) { this->size = other.size; this->elements = new T[size]; for (int i = 0; i < size; i++) { this->elements[i] = other.elements[i]; } } template Set::Set() { elements = nullptr; size = 0; } template Set::~Set() { delete[] elements; } template Set::Set(const Set& other) { copyFrom(other); } template Set& Set::operator=(const Set& other) { if (this != &other) { free(); copyFrom(other); } return *this; } template Set::Set(Set&& other) { this->size = other.size; this->elements = other.elements; other.elements = nullptr; } template Set& Set::operator=(Set&& other) { if (this != &other) { free(); this->size = other.size; this->elements = other.elements; other.elements = nullptr; } return *this; } template Set& Set::operator+=(const Set& right) { T* biggerArray = new T[size + right.size]; for (int i = 0; i < size; i++) { biggerArray[i] = elements[i]; } for (int i = 0; i < right.size; i++) { biggerArray[i+size] = right.elements[i]; } delete[] elements; elements = biggerArray; size += right.size; return *this; } template Set operator+(const Set& left, const Set& right) { Set setUnion = left; setUnion += right; return setUnion; } template Set& Set::operator*=(const Set& right) { T* commonArray = new T[size]; unsigned commonCount = 0; for (int i = 0; i < size; i++) { for (int j = 0; j < right.size; j++) { if (elements[i] == right.elements[j]) { commonArray[commonCount++] = elements[i]; break; } } } size = commonCount; delete[] elements; elements = new T[size]; for (int i = 0; i < size; i++) { elements[i] = commonArray[i]; } delete[] commonArray; return *this; } template Set operator*(const Set& left, const Set& right) { Set setIntersection = left; setIntersection *= right; return setIntersection; } template Set& Set::operator-=(const Set& right) { Set complement = right * (*this); *this = complement; return *this; } template Set operator-(const Set& left, const Set& right) { Set setComplement = left; setComplement -= right; return setComplement; }