diff --git a/include/tmatrix.h b/include/tmatrix.h index 6c11b2feb..485b5fdb2 100644 --- a/include/tmatrix.h +++ b/include/tmatrix.h @@ -8,11 +8,15 @@ #define __TDynamicMatrix_H__ #include +#include +#include using namespace std; const int MAX_VECTOR_SIZE = 100000000; const int MAX_MATRIX_SIZE = 10000; +const int FLOAT_EPSILON = 1e-6; +const int DOUBLE_EPSILON = 1e-14; // Динамический вектор - // шаблонный вектор на динамической памяти @@ -20,35 +24,63 @@ template class TDynamicVector { protected: - size_t sz; - T* pMem; + size_t sz = 0; + T* pMem = nullptr; public: - TDynamicVector(size_t size = 1) : sz(size) + TDynamicVector(size_t s = 1) : sz(s) { - if (sz == 0) - throw out_of_range("Vector size should be greater than zero"); - pMem = new T[sz]();// {}; // У типа T д.б. констуктор по умолчанию + if (sz == 0) + throw out_of_range("Vector size should be greater than zero"); + if (sz > MAX_VECTOR_SIZE) + throw out_of_range("Vector is too large"); + pMem = new T[sz](); } TDynamicVector(T* arr, size_t s) : sz(s) { - assert(arr != nullptr && "TDynamicVector ctor requires non-nullptr arg"); - pMem = new T[sz]; - std::copy(arr, arr + sz, pMem); + assert(arr != nullptr && "TDynamicVector ctor requires non-nullptr arg"); + if (sz > MAX_VECTOR_SIZE) + throw out_of_range("Vector is too large"); + pMem = new T[sz]; + std::copy(arr, arr + sz, pMem); } - TDynamicVector(const TDynamicVector& v) + TDynamicVector(const TDynamicVector& v) : sz(v.sz) { + pMem = new T[sz]; + std::copy(v.pMem, v.pMem + sz, pMem); } - TDynamicVector(TDynamicVector&& v) noexcept + TDynamicVector(TDynamicVector&& v) noexcept : sz(v.sz), pMem(v.pMem) { + v.pMem = nullptr; + v.sz = 0; } ~TDynamicVector() { + delete[] pMem; } TDynamicVector& operator=(const TDynamicVector& v) { + if (this != &v) + { + if (sz != v.sz) + { + delete[] pMem; + sz = v.sz; + pMem = new T[sz]; + } + std::copy(v.pMem, v.pMem + sz, pMem); + } + return *this; } TDynamicVector& operator=(TDynamicVector&& v) noexcept { + if (this != &v) + { + delete[] pMem; + sz = v.sz; + pMem = v.pMem; + v.pMem = nullptr; + v.sz = 0; + } return *this; } @@ -57,65 +89,142 @@ class TDynamicVector // индексация T& operator[](size_t ind) { + return pMem[ind]; } const T& operator[](size_t ind) const { + return pMem[ind]; } // индексация с контролем T& at(size_t ind) { + if(ind >= 0 && ind < sz) + return pMem[ind]; + else + throw out_of_range("Index out of range"); } const T& at(size_t ind) const { + if (ind >= 0 && ind < sz) + return pMem[ind]; + else + throw out_of_range("Index out of range"); } // сравнение bool operator==(const TDynamicVector& v) const noexcept { + if (sz != v.sz) return false; + for (size_t i = 0; i < sz; i++) + { + if (std::is_integral::value) + { + if (pMem[i] != v.pMem[i]) + return false; + } + else if (std::is_same::value) + { + if (std::abs(pMem[i] - v.pMem[i]) > static_cast(FLOAT_EPSILON)) + return false; + } + else if (std::is_same::value) + { + if (std::abs(pMem[i] - v.pMem[i]) > static_cast(DOUBLE_EPSILON)) + return false; + } + else + { + if (pMem[i] != v.pMem[i]) return false; + } + } + return true; } bool operator!=(const TDynamicVector& v) const noexcept { + return !(*this == v); } // скалярные операции TDynamicVector operator+(T val) { + TDynamicVector res(sz); + for (size_t i = 0; i < sz; i++) + { + res[i] = pMem[i] + val; + } + return res; } - TDynamicVector operator-(double val) + TDynamicVector operator-(T val) { + TDynamicVector res(sz); + for (size_t i = 0; i < sz; i++) + { + res[i] = pMem[i] - val; + } + return res; } - TDynamicVector operator*(double val) + TDynamicVector operator*(T val) { + TDynamicVector res(sz); + for (size_t i = 0; i < sz; i++) + { + res[i] = pMem[i] * val; + } + return res; } // векторные операции TDynamicVector operator+(const TDynamicVector& v) { + if (sz != v.sz) + throw invalid_argument("Vector sizes are not EQ"); + TDynamicVector res(sz); + for (size_t i = 0; i < sz; i++) + { + res[i] = pMem[i] + v.pMem[i]; + } + return res; } TDynamicVector operator-(const TDynamicVector& v) { + if (sz != v.sz) + throw invalid_argument("Vector sizes are not EQ"); + TDynamicVector res(sz); + for (size_t i = 0; i < sz; i++) + { + res[i] = pMem[i] - v.pMem[i]; + } + return res; } - T operator*(const TDynamicVector& v) noexcept(noexcept(T())) + T operator*(const TDynamicVector& v) { + if (sz != v.sz) + throw invalid_argument("Vector sizes are not EQ"); + T result = T(); + for (size_t i = 0; i < sz; i++) + { + result += pMem[i] * v.pMem[i]; + } + return result; } friend void swap(TDynamicVector& lhs, TDynamicVector& rhs) noexcept { - std::swap(lhs.sz, rhs.sz); - std::swap(lhs.pMem, rhs.pMem); + std::swap(lhs.sz, rhs.sz); + std::swap(lhs.pMem, rhs.pMem); } // ввод/вывод friend istream& operator>>(istream& istr, TDynamicVector& v) { for (size_t i = 0; i < v.sz; i++) - istr >> v.pMem[i]; // требуется оператор>> для типа T + istr >> v.pMem[i]; return istr; } friend ostream& operator<<(ostream& ostr, const TDynamicVector& v) { for (size_t i = 0; i < v.sz; i++) - ostr << v.pMem[i] << ' '; // требуется оператор<< для типа T + ostr << v.pMem[i] << ' '; return ostr; } }; @@ -129,46 +238,127 @@ class TDynamicMatrix : private TDynamicVector> using TDynamicVector>::pMem; using TDynamicVector>::sz; public: - TDynamicMatrix(size_t s = 1) : TDynamicVector>(s) + TDynamicMatrix(size_t s = 1) { - for (size_t i = 0; i < sz; i++) - pMem[i] = TDynamicVector(sz); + if (s <= 0) + throw out_of_range("Matrix size should be greater than zero"); + if (s > MAX_MATRIX_SIZE) + throw out_of_range("Matrix is too large"); + this->sz = s; + this->pMem = new TDynamicVector[s]; + for (size_t i = 0; i < sz; i++) + { + pMem[i] = TDynamicVector(sz); + } } using TDynamicVector>::operator[]; + size_t size() const noexcept { return sz; } // сравнение bool operator==(const TDynamicMatrix& m) const noexcept { + if (sz != m.sz) return false; + for (size_t i = 0; i < sz; i++) + { + if (pMem[i] != m.pMem[i]) return false; + } + return true; + } + bool operator!=(const TDynamicMatrix& m) const noexcept + { + return !(*this == m); } // матрично-скалярные операции TDynamicVector operator*(const T& val) { + TDynamicVector res(sz); + for (size_t i = 0; i < sz; i++) + { + res[i] = pMem[i] * val; + } + return res; } // матрично-векторные операции TDynamicVector operator*(const TDynamicVector& v) { + if (sz != v.size()) + throw invalid_argument("Matrix and vector must be equal"); + TDynamicVector res(sz); + for (size_t i = 0; i < sz; i++) + { + res[i] = T(); + for (size_t j = 0; j < sz; j++) + { + res[i] += pMem[i][j] * v[j]; + } + } + return res; } // матрично-матричные операции TDynamicMatrix operator+(const TDynamicMatrix& m) { + TDynamicMatrix res(sz); + for (size_t i = 0; i < sz; i++) + { + res[i] = pMem[i] + m.pMem[i]; + } + return res; } TDynamicMatrix operator-(const TDynamicMatrix& m) { + TDynamicMatrix res(sz); + for (size_t i = 0; i < sz; i++) + { + res[i] = pMem[i] - m.pMem[i]; + } + return res; } TDynamicMatrix operator*(const TDynamicMatrix& m) { + if (sz != m.size()) + throw invalid_argument("Matrix1 and Matrix2 must be equal n1 and m2"); + TDynamicMatrix res(sz); + for (size_t i = 0; i < sz; i++) + { + for (size_t j = 0; j < sz; j++) + { + res[i][j] = T(); + for (size_t k = 0; k < sz; k++) + { + res[i][j] += pMem[i][k] * m.pMem[k][j]; + } + } + } + return res; } // ввод/вывод - friend istream& operator>>(istream& istr, TDynamicMatrix& v) + friend istream& operator>>(istream& istr, TDynamicMatrix& m) { + for (size_t i = 0; i < m.sz; i++) + { + for (size_t j = 0; j < m.sz; j++) + { + istr >> m.pMem[i][j]; + } + } + return istr; } - friend ostream& operator<<(ostream& ostr, const TDynamicMatrix& v) + friend ostream& operator<<(ostream& ostr, const TDynamicMatrix& m) { + for (size_t i = 0; i < m.sz; i++) + { + for (size_t j = 0; j < m.sz; j++) + { + ostr << m.pMem[i][j] << ' '; + } + ostr << endl; + } + return ostr; } }; diff --git a/test/test_tmatrix.cpp b/test/test_tmatrix.cpp index edaf75ef6..d3ca19d37 100644 --- a/test/test_tmatrix.cpp +++ b/test/test_tmatrix.cpp @@ -4,108 +4,466 @@ TEST(TDynamicMatrix, can_create_matrix_with_positive_length) { - ASSERT_NO_THROW(TDynamicMatrix m(5)); + ASSERT_NO_THROW(TDynamicMatrix m(5)); } TEST(TDynamicMatrix, cant_create_too_large_matrix) { - ASSERT_ANY_THROW(TDynamicMatrix m(MAX_MATRIX_SIZE + 1)); + ASSERT_ANY_THROW(TDynamicMatrix m(MAX_MATRIX_SIZE + 1)); } TEST(TDynamicMatrix, throws_when_create_matrix_with_negative_length) { - ASSERT_ANY_THROW(TDynamicMatrix m(-5)); + ASSERT_ANY_THROW(TDynamicMatrix m(-5)); } TEST(TDynamicMatrix, can_create_copied_matrix) { - TDynamicMatrix m(5); + TDynamicMatrix m(5); - ASSERT_NO_THROW(TDynamicMatrix m1(m)); + ASSERT_NO_THROW(TDynamicMatrix m1(m)); } TEST(TDynamicMatrix, copied_matrix_is_equal_to_source_one) { - ADD_FAILURE(); + int size = 5; + TDynamicMatrix m(size); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + m[i][j] = i * size + j; + } + } + TDynamicMatrix m1(m); + + bool flag = true; + if (m.size() != m1.size()) + flag = false; + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + if (m[i][j] != m1[i][j]) + flag = false; + } + } + EXPECT_TRUE(flag); + //ADD_FAILURE(); } TEST(TDynamicMatrix, copied_matrix_has_its_own_memory) { - ADD_FAILURE(); + int size = 10; + TDynamicMatrix m(size); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + m[i][j] = i * size + j; + } + } + TDynamicMatrix m1(m); + /* + EXPECT_TRUE(&m != &m1); + EXPECT_EQ(m.size(), m1.size()); + EXPECT_EQ(size, m1.size()); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + EXPECT_EQ(m[i][j], m1[i][j]); + } + } + */ + int OrgVal = m[0][0]; + + m[0][0] = 999; + + EXPECT_TRUE(&m != &m1); + EXPECT_TRUE(OrgVal != m[0][0]); + EXPECT_TRUE(OrgVal == m1[0][0]); + //ADD_FAILURE(); } -TEST(TDynamicMatrix, can_get_size) +TEST(TDynamicMatrix, can_get_size) //IT WAS NOT IN .h FILE!!! { - ADD_FAILURE(); + int size = 4; + TDynamicMatrix m(size); + + EXPECT_EQ(4, m.size()); + //ADD_FAILURE(); } TEST(TDynamicMatrix, can_set_and_get_element) { - ADD_FAILURE(); + int size = 4; + TDynamicMatrix m(size); + m[0][0] = 4; + + EXPECT_EQ(4, m[0][0]); + //ADD_FAILURE(); } TEST(TDynamicMatrix, throws_when_set_element_with_negative_index) { - ADD_FAILURE(); + int size = 4; + TDynamicMatrix m(size); + + ASSERT_ANY_THROW(m[0].at(-1) = 4); + //ADD_FAILURE(); } TEST(TDynamicMatrix, throws_when_set_element_with_too_large_index) { - ADD_FAILURE(); + int size = 4; + TDynamicMatrix m(size); + + ASSERT_ANY_THROW(m[3].at(4) = 4); + //ADD_FAILURE(); } TEST(TDynamicMatrix, can_assign_matrix_to_itself) { - ADD_FAILURE(); + int size = 5; + TDynamicMatrix m(size); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + m[i][j] = i * size + j; + } + } + + m = m; + EXPECT_EQ(m.size(), 5); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + EXPECT_EQ(m[i][j], i * size + j); + } + } + //ADD_FAILURE(); } TEST(TDynamicMatrix, can_assign_matrices_of_equal_size) { - ADD_FAILURE(); + int size = 5; + TDynamicMatrix m(size); + TDynamicMatrix m1(size); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + m[i][j] = i * size + j; + } + } + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + m1[i][j] = i * size + j + 1; + } + } + + m = m1; + EXPECT_EQ(m.size(), size); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + EXPECT_EQ(m[i][j], i * size + j + 1); + } + } + //ADD_FAILURE(); } TEST(TDynamicMatrix, assign_operator_change_matrix_size) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 10; + TDynamicMatrix m(size1); + TDynamicMatrix m1(size2); + for (int i = 0; i < size1; i++) + { + for (int j = 0; j < size1; j++) + { + m[i][j] = i * size1 + j; + } + } + for (int i = 0; i < size2; i++) + { + for (int j = 0; j < size2; j++) + { + m1[i][j] = i * size2 + j + 1; + } + } + + m = m1; + EXPECT_EQ(m.size(), size2); + //ADD_FAILURE(); } TEST(TDynamicMatrix, can_assign_matrices_of_different_size) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 10; + TDynamicMatrix m(size1); + TDynamicMatrix m1(size2); + for (int i = 0; i < size1; i++) + { + for (int j = 0; j < size1; j++) + { + m[i][j] = i * size1 + j; + } + } + for (int i = 0; i < size2; i++) + { + for (int j = 0; j < size2; j++) + { + m1[i][j] = i * size2 + j + 1; + } + } + + m = m1; + for (int i = 0; i < m.size(); i++) + { + for (int j = 0; j < m.size(); j++) + { + EXPECT_EQ(m[i][j], i * m.size() + j + 1); + } + } + //ADD_FAILURE(); } TEST(TDynamicMatrix, compare_equal_matrices_return_true) { - ADD_FAILURE(); + int size = 5; + TDynamicMatrix m(size); + m[0][1] = 2; + m[1][2] = 3; + TDynamicMatrix m1(size); + m1[0][1] = 2; + m1[1][2] = 3; + + EXPECT_TRUE(m == m1); + //ADD_FAILURE(); } TEST(TDynamicMatrix, compare_matrix_with_itself_return_true) { - ADD_FAILURE(); + int size = 5; + TDynamicMatrix m(size); + m[0][1] = 2; + m[1][2] = 3; + + EXPECT_TRUE(m == m); + //ADD_FAILURE(); } TEST(TDynamicMatrix, matrices_with_different_size_are_not_equal) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 4; + TDynamicMatrix m(size1); + m[0][1] = 2; + m[1][2] = 3; + TDynamicMatrix m1(size2); + m1[0][1] = 2; + m1[1][2] = 3; + + EXPECT_TRUE(m != m1); + //ADD_FAILURE(); } TEST(TDynamicMatrix, can_add_matrices_with_equal_size) { - ADD_FAILURE(); + int size = 5; + TDynamicMatrix m(size); + TDynamicMatrix m1(size); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + m[i][j] = i * size + j; + } + } + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + m1[i][j] = i * size + j + 1; + } + } + TDynamicMatrix res = m + m1; + + EXPECT_EQ(res.size(), size); + for (int i = 0; i < m.size(); i++) + { + for (int j = 0; j < m.size(); j++) + { + EXPECT_EQ(res[i][j], 2 * i * m.size() + 2 * j + 1); + } + } + //ADD_FAILURE(); } TEST(TDynamicMatrix, cant_add_matrices_with_not_equal_size) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 4; + TDynamicMatrix m(size1); + TDynamicMatrix m1(size2); + for (int i = 0; i < size1; i++) + { + for (int j = 0; j < size1; j++) + { + m[i][j] = i * size1 + j; + } + } + for (int i = 0; i < size2; i++) + { + for (int j = 0; j < size2; j++) + { + m1[i][j] = i * size2 + j + 1; + } + } + + ASSERT_ANY_THROW(TDynamicMatrix res = m + m1); + //ADD_FAILURE(); } TEST(TDynamicMatrix, can_subtract_matrices_with_equal_size) { - ADD_FAILURE(); + int size = 5; + TDynamicMatrix m(size); + TDynamicMatrix m1(size); + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + m[i][j] = i * size + j; + } + } + for (int i = 0; i < size; i++) + { + for (int j = 0; j < size; j++) + { + m1[i][j] = i * size + j + 1; + } + } + TDynamicMatrix res = m - m1; + + EXPECT_EQ(res.size(), size); + for (int i = 0; i < m.size(); i++) + { + for (int j = 0; j < m.size(); j++) + { + EXPECT_EQ(res[i][j], -1); + } + } + //ADD_FAILURE(); } TEST(TDynamicMatrix, cant_subtract_matrixes_with_not_equal_size) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 4; + TDynamicMatrix m(size1); + TDynamicMatrix m1(size2); + for (int i = 0; i < size1; i++) + { + for (int j = 0; j < size1; j++) + { + m[i][j] = i * size1 + j; + } + } + for (int i = 0; i < size2; i++) + { + for (int j = 0; j < size2; j++) + { + m1[i][j] = i * size2 + j + 1; + } + } + + ASSERT_ANY_THROW(TDynamicMatrix res = m - m1); + //ADD_FAILURE(); +} + +TEST(TDynamicMatrix, can_create_matrix_with_move_semantics) +{ + int size = 3; + TDynamicMatrix m1(3); + for (size_t i = 0; i < size; i++) + for (size_t j = 0; j < size; j++) + m1[i][j] = i * size + j; + TDynamicMatrix m2(std::move(m1)); + + EXPECT_EQ(m1.size(), 0); + EXPECT_EQ(m2.size(), size); + for (size_t i = 0; i < m2.size(); i++) + for (size_t j = 0; j < m2.size(); j++) + EXPECT_EQ(m2[i][j], i * m2.size() + j); + //ADD_FAILURE(); +} + +TEST(TDynamicMatrix, move_assignment_operator_works_correctly_for_matrices) +{ + int size1 = 3; + int size2 = 2; + TDynamicMatrix m1(size1); + TDynamicMatrix m2(size2); + for (size_t i = 0; i < size1; i++) + for (size_t j = 0; j < size1; j++) + m1[i][j] = static_cast(i * size1 + j); + for (size_t i = 0; i < size2; i++) + for (size_t j = 0; j < size2; j++) + m2[i][j] = static_cast(i * size2 + j + 100); + m2 = std::move(m1); + + EXPECT_EQ(m1.size(), 0); + EXPECT_EQ(m2.size(), size1); + for (size_t i = 0; i < m2.size(); i++) + for (size_t j = 0; j < m2.size(); j++) + EXPECT_EQ(m2[i][j], i * m2.size() + j); + //ADD_FAILURE(); +} + +TEST(TDynamicMatrix, moved_from_matrix_can_be_reused) +{ + int size1 = 3; + int size2 = 2; + TDynamicMatrix m1(size1); + for (size_t i = 0; i < size1; i++) + for (size_t j = 0; j < size1; j++) + m1[i][j] = i * size1 + j; + TDynamicMatrix m2 = std::move(m1); + m1 = TDynamicMatrix(2); + for (size_t i = 0; i < size2; i++) + for (size_t j = 0; j < size2; j++) + m1[i][j] = i * size2 + j + 100; + + EXPECT_EQ(m1.size(), size2); + for (size_t i = 0; i < m1.size(); i++) + for (size_t j = 0; j < m1.size(); j++) + EXPECT_EQ(m1[i][j], i * size2 + j + 100); + //ADD_FAILURE(); +} + +TEST(TDynamicMatrix, self_move_assignment_does_not_crash) +{ + int size = 3; + TDynamicMatrix m(size); + for (size_t i = 0; i < size; i++) + for (size_t j = 0; j < size; j++) + m[i][j] = i * size + j; + m = std::move(m); + + EXPECT_EQ(m.size(), size); + for (size_t i = 0; i < m.size(); i++) + for (size_t j = 0; j < m.size(); j++) + EXPECT_EQ(m[i][j], i * size + j); + //ADD_FAILURE(); } diff --git a/test/test_tvector.cpp b/test/test_tvector.cpp index 1f7737755..48440e3c0 100644 --- a/test/test_tvector.cpp +++ b/test/test_tvector.cpp @@ -4,138 +4,469 @@ TEST(TDynamicVector, can_create_vector_with_positive_length) { - ASSERT_NO_THROW(TDynamicVector v(5)); + ASSERT_NO_THROW(TDynamicVector v(5)); } TEST(TDynamicVector, cant_create_too_large_vector) { - ASSERT_ANY_THROW(TDynamicVector v(MAX_VECTOR_SIZE + 1)); + ASSERT_ANY_THROW(TDynamicVector v(MAX_VECTOR_SIZE + 1)); } TEST(TDynamicVector, throws_when_create_vector_with_negative_length) { - ASSERT_ANY_THROW(TDynamicVector v(-5)); + ASSERT_ANY_THROW(TDynamicVector v(-5)); } TEST(TDynamicVector, can_create_copied_vector) { - TDynamicVector v(10); + int size = 10; + TDynamicVector v(size); - ASSERT_NO_THROW(TDynamicVector v1(v)); + ASSERT_NO_THROW(TDynamicVector v1(v)); } TEST(TDynamicVector, copied_vector_is_equal_to_source_one) { - ADD_FAILURE(); + int size = 10; + TDynamicVector v(size); + for (size_t i = 0; i < size; i++) + { + v[i] = i; + } + TDynamicVector v1(v); + + bool flag = true; + if (v.size() != v1.size()) + { + flag = false; + } + for (int i = 0; i < v.size(); i++) + { + if(v[i] != v1[i]) + flag = false; + } + EXPECT_TRUE(flag); + //ADD_FAILURE(); } TEST(TDynamicVector, copied_vector_has_its_own_memory) { - ADD_FAILURE(); + int size = 10; + TDynamicVector v(size); + for (size_t i = 0; i < size; i++) + { + v[i] = i; + } + TDynamicVector v1(v); + + EXPECT_TRUE(&v != &v1); + EXPECT_EQ(v.size(), v1.size()); + EXPECT_EQ(size, v1.size()); + for (int i = 0; i < size; ++i) + { + EXPECT_EQ(v[i], v1[i]); + } + int OrgVal = v[0]; + v[0] = 999; + EXPECT_TRUE(OrgVal != v[0]); + EXPECT_TRUE(OrgVal == v1[0]); + //ADD_FAILURE(); } TEST(TDynamicVector, can_get_size) { - TDynamicVector v(4); + int size = 4; + TDynamicVector v(size); - EXPECT_EQ(4, v.size()); + EXPECT_EQ(4, v.size()); } -//TEST(TDynamicVector, can_set_and_get_element) -//{ -// TDynamicVector v(4); -// v[0] = 4; -// -// EXPECT_EQ(4, v[0]); -//} +TEST(TDynamicVector, can_set_and_get_element) +{ + int size = 4; + TDynamicVector v(size); + v[0] = 4; + + EXPECT_EQ(4, v[0]); +} TEST(TDynamicVector, throws_when_set_element_with_negative_index) { - ADD_FAILURE(); + int size = 4; + TDynamicVector v(size); + + ASSERT_ANY_THROW(v.at(-1) = 4); + //ADD_FAILURE(); } TEST(TDynamicVector, throws_when_set_element_with_too_large_index) { - ADD_FAILURE(); + int size = 4; + TDynamicVector v(size); + + ASSERT_ANY_THROW(v.at(4) = 4); + //ADD_FAILURE(); } TEST(TDynamicVector, can_assign_vector_to_itself) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + for (int i = 0; i < v.size(); i++) + { + v[i] = i * 5; + } + + v = v; + EXPECT_EQ(v.size(), 5); + for (int i = 0; i < v.size(); i++) + { + EXPECT_EQ(v[i], i * 5); + } + //ADD_FAILURE(); } TEST(TDynamicVector, can_assign_vectors_of_equal_size) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + TDynamicVector v1(size); + for (int i = 0; i < size; i++) + { + v[i] = i * 5; + } + for (int i = 0; i < size; i++) + { + v1[i] = i * 10; + } + + v = v1; + EXPECT_EQ(v.size(), size); + for (int i = 0; i < v.size(); i++) + { + EXPECT_EQ(v[i], i * 10); + } + //ADD_FAILURE(); } TEST(TDynamicVector, assign_operator_change_vector_size) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 10; + TDynamicVector v(size1); + TDynamicVector v1(size2); + for (int i = 0; i < size1; i++) + { + v[i] = i * 5; + } + for (int i = 0; i < size2; i++) + { + v1[i] = i * 10; + } + + v = v1; + EXPECT_EQ(v.size(), size2); + //ADD_FAILURE(); } TEST(TDynamicVector, can_assign_vectors_of_different_size) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 10; + TDynamicVector v(size1); + TDynamicVector v1(size2); + for (int i = 0; i < size1; i++) + { + v[i] = i * 5; + } + for (int i = 0; i < size2; i++) + { + v1[i] = i * 10; + } + + v = v1; + for (int i = 0; i < v.size(); i++) + { + EXPECT_EQ(v[i], i * 10); + } + //ADD_FAILURE(); } TEST(TDynamicVector, compare_equal_vectors_return_true) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + v[1] = 2; + v[2] = 3; + TDynamicVector v1(size); + v1[1] = 2; + v1[2] = 3; + + EXPECT_TRUE(v == v1); + //ADD_FAILURE(); } TEST(TDynamicVector, compare_vector_with_itself_return_true) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + v[1] = 2; + v[2] = 3; + + EXPECT_TRUE(v == v); + //ADD_FAILURE(); } TEST(TDynamicVector, vectors_with_different_size_are_not_equal) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 4; + TDynamicVector v(size1); + v[1] = 2; + v[2] = 3; + TDynamicVector v1(size2); + v1[1] = 2; + v1[2] = 3; + + EXPECT_TRUE(v != v1); //Normal test because != starts == + //ADD_FAILURE(); } TEST(TDynamicVector, can_add_scalar_to_vector) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + for (int i = 0; i < size; i++) + { + v[i] = i * 5; + } + TDynamicVector res = v + 5; + + EXPECT_EQ(res.size(), size); + for (int i = 0; i < size; i++) + { + EXPECT_EQ(res[i], i * 5 + 5); + } + //ADD_FAILURE(); } TEST(TDynamicVector, can_subtract_scalar_from_vector) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + for (int i = 0; i < size; i++) + { + v[i] = i * 5; + } + TDynamicVector res = v - 5; + + EXPECT_EQ(res.size(), size); + for (int i = 0; i < size; i++) + { + EXPECT_EQ(res[i], i * 5 - 5); + } + //ADD_FAILURE(); } TEST(TDynamicVector, can_multiply_scalar_by_vector) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + for (int i = 0; i < size; i++) + { + v[i] = i * 5; + } + TDynamicVector res = v * 5; + + EXPECT_EQ(res.size(), size); + for (int i = 0; i < size; i++) + { + EXPECT_EQ(res[i], i * 5 * 5); + } + //ADD_FAILURE(); } TEST(TDynamicVector, can_add_vectors_with_equal_size) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + TDynamicVector v1(size); + for (int i = 0; i < size; i++) + { + v[i] = i * 2; + } + for (int i = 0; i < size; i++) + { + v1[i] = i * 3; + } + TDynamicVector res = v + v1; + + EXPECT_EQ(res.size(), size); + for (int i = 0; i < size; i++) + { + EXPECT_EQ(res[i], 5 * i); + } + //ADD_FAILURE(); } TEST(TDynamicVector, cant_add_vectors_with_not_equal_size) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 4; + TDynamicVector v(size1); + TDynamicVector v1(size2); + for (int i = 0; i < size1; i++) + { + v[i] = i * 2; + } + for (int i = 0; i < size2; i++) + { + v1[i] = i * 3; + } + ASSERT_ANY_THROW(TDynamicVector res = v + v1); + //ADD_FAILURE(); } TEST(TDynamicVector, can_subtract_vectors_with_equal_size) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + TDynamicVector v1(size); + for (int i = 0; i < size; i++) + { + v[i] = i * 2; + } + for (int i = 0; i < size; i++) + { + v1[i] = i * 3; + } + TDynamicVector res = v - v1; + + EXPECT_EQ(res.size(), size); + for (int i = 0; i < size; i++) + { + EXPECT_EQ(res[i], (-1)* i); + } + //ADD_FAILURE(); } TEST(TDynamicVector, cant_subtract_vectors_with_not_equal_size) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 4; + TDynamicVector v(size1); + TDynamicVector v1(size2); + for (int i = 0; i < size1; i++) + { + v[i] = i * 2; + } + for (int i = 0; i < size2; i++) + { + v1[i] = i * 3; + } + ASSERT_ANY_THROW(TDynamicVector res = v - v1); + //ADD_FAILURE(); } TEST(TDynamicVector, can_multiply_vectors_with_equal_size) { - ADD_FAILURE(); + int size = 5; + TDynamicVector v(size); + TDynamicVector v1(size); + for (int i = 0; i < size; i++) + { + v[i] = i * 2; + } + for (int i = 0; i < size; i++) + { + v1[i] = i * 3; + } + int res = v * v1; + + EXPECT_EQ(res, 0*0 + 2*3 + 4*6 + 6*9 + 8*12); + //ADD_FAILURE(); } TEST(TDynamicVector, cant_multiply_vectors_with_not_equal_size) { - ADD_FAILURE(); + int size1 = 5; + int size2 = 4; + TDynamicVector v(size1); + TDynamicVector v1(size2); + for (int i = 0; i < size1; i++) + { + v[i] = i * 2; + } + for (int i = 0; i < size2; i++) + { + v1[i] = i * 3; + } + ASSERT_ANY_THROW(int res = v * v1); + //ADD_FAILURE(); +} + +TEST(TDynamicVector, can_create_vector_with_move_semantics) +{ + int size = 5; + TDynamicVector v1(size); + for (size_t i = 0; i < size; i++) + v1[i] = i; + TDynamicVector v2(std::move(v1)); + + EXPECT_EQ(v1.size(), 0); + EXPECT_EQ(v2.size(), size); + for (size_t i = 0; i < v2.size(); i++) + EXPECT_EQ(v2[i], i); + //ADD_FAILURE(); +} + +TEST(TDynamicVector, move_assignment_operator_works_correctly) +{ + int size1 = 5; + int size2 = 3; + TDynamicVector v1(size1); + TDynamicVector v2(size2); + for (size_t i = 0; i < size1; i++) + v1[i] = i; + for (size_t i = 0; i < size2; i++) + v2[i] = i + 10; + v2 = std::move(v1); + + EXPECT_EQ(v1.size(), 0); + EXPECT_EQ(v2.size(), size1); + for (size_t i = 0; i < v2.size(); i++) + EXPECT_EQ(v2[i], i); + //ADD_FAILURE(); +} + +TEST(TDynamicVector, moved_from_vector_can_be_reused) +{ + int size = 5; + TDynamicVector v1(size); + for (size_t i = 0; i < size; i++) + v1[i] = i + 1; + TDynamicVector v2 = std::move(v1); + v1 = TDynamicVector(size); + for (size_t i = 0; i < size; i++) + v1[i] = i + 100; + + EXPECT_EQ(v1.size(), size); + for (size_t i = 0; i < v1.size(); i++) + EXPECT_EQ(v1[i], i + 100); + //ADD_FAILURE(); +} + +TEST(TDynamicVector, self_move_assignment_does_not_crash) +{ + int size = 5; + TDynamicVector v(size); + for (size_t i = 0; i < v.size(); i++) + v[i] = i; + v = std::move(v); + + EXPECT_EQ(v.size(), size); + for (size_t i = 0; i < v.size(); i++) + EXPECT_EQ(v[i], i); + //ADD_FAILURE(); }