diff --git a/2025-2026/Week 14/Readme.md b/2025-2026/Week 14/Readme.md index 119372c..5455830 100644 --- a/2025-2026/Week 14/Readme.md +++ b/2025-2026/Week 14/Readme.md @@ -26,8 +26,8 @@ _Бонус_: _Бонус_: * or_else - ако съдържа стойност, връща самият обект, иначе връща резултат от подадена функция -* and_then - ако съдържа стойност, връща резултата от подадена функция,иначе връща празен обект -* transform - ако съдържа стойност, връща обект съдържащ резултата от подадена функция, иначе връща празен обект +* and_then - ако съдържа стойност, връща резултата от подадена функция, изпълнена върху стойността, иначе връща празен обект +* transform - ако съдържа стойност, връща обект съдържащ резултата от подадена функция, изпълнена върху стойността, иначе връща празен обект **Задача 3:** diff --git a/2025-2026/Week 14/Solutions/include/Either.hpp b/2025-2026/Week 14/Solutions/include/Either.hpp new file mode 100644 index 0000000..21db468 --- /dev/null +++ b/2025-2026/Week 14/Solutions/include/Either.hpp @@ -0,0 +1,198 @@ +#pragma once + +#include +#include + +template +class Either { + Left* leftValue; + Right* rightValue; + bool isLeft; + + void copy(const Either &other); + + void move(Either &&other) noexcept; + + void free(); + +public: + Either(const Left &left); + Either(const Right &right); + + Either(Left &&left); + Either(Right &&right); + + Either(const Either &other); + Either(Either &&other) noexcept; + Either &operator=(const Either &other); + Either &operator=(Either &&other) noexcept; + + bool is_left() const; + bool is_right() const; + + Left &left() &; + const Left &left() const&; + Left&& left() &&; + + Right &right() &; + const Right &right() const&; + Right &&right() &&; + + template + Either transform_left(const std::function &f) const; + + template + Either transform_right(const std::function &f) const; + + template + Either and_then(const std::function(const Left &)> &f) const; + + template + Either visit(const std::function &left, + const std::function &right); +}; + +template +template +Either Either::visit(const std::function &left, const std::function &right) { + if (is_left()) + return left(this->left()); + else + return right(this->right()); +} + +template +template +Either Either::and_then(const std::function(const Left &)> &f) const { + if (is_left()) + return f(left()); + else + return Either(right()); +} + +template +template +Either Either::transform_right(const std::function &f) const { + if (is_left()) + return Either(left()); + else + return Either(f(right())); +} + +template +template +Either Either::transform_left(const std::function &f) const { + if (is_left()) + return Either(f(left())); + else + return Either(right()); +} + +template +void Either::copy(const Either &other) { + isLeft = other.isLeft; + if (isLeft) { + leftValue = new Left(other.left()); + rightValue = nullptr; + } + else { + rightValue = new Right(other.right()); + leftValue = nullptr; + } +} +template +void Either::move(Either &&other) noexcept{ + std::swap(isLeft, other.isLeft); + std::swap(leftValue, other.leftValue); + std::swap(rightValue, other.rightValue); +} +template void Either::free() { + if (isLeft) { + delete leftValue; + } + else { + delete rightValue; + } +} +template +Either::Either(const Left &left) + : leftValue(new Left(left)), rightValue(nullptr), isLeft(true) {} + +template +Either::Either(const Right &right) + : leftValue(nullptr), rightValue(new Right(right)), isLeft(false) {} + +template +Either::Either(Left &&left) + : leftValue(new Left(std::move(left))), rightValue(nullptr), isLeft(true) {} + +template +Either::Either(Right &&right) + : leftValue(nullptr), rightValue(new Right(std::move(right))), isLeft(false) {} + +template +Either::Either(const Either &other) { + copy(other); +} + +template +Either::Either(Either &&other) noexcept { + move(std::move(other)); +} + +template +Either &Either::operator=(const Either &other) { + if (this != &other) { + free(); + copy(other); + } + return *this; +} +template +Either &Either::operator=(Either &&other) noexcept { + if (this != &other) { + free(); + move(std::move(other)); + } + return *this; +} + +template +bool Either::is_left() const { + return isLeft; +} + +template +bool Either::is_right() const { + return !isLeft; +} + +template +const Left &Either::left() const& { + return *leftValue; +} + +template +Left &Either::left() &{ + return *leftValue; +} + +template +const Right &Either::right() const& { + return *rightValue; +} + +template +Right &Either::right() &{ + return *rightValue; +} + +template +Left &&Either::left() &&{ + return std::move(*leftValue); +} + +template +Right &&Either::right() &&{ + return std::move(*rightValue); +} diff --git a/2025-2026/Week 14/Solutions/include/Optional.hpp b/2025-2026/Week 14/Solutions/include/Optional.hpp new file mode 100644 index 0000000..d7a876d --- /dev/null +++ b/2025-2026/Week 14/Solutions/include/Optional.hpp @@ -0,0 +1,184 @@ +#pragma once +#include +#include + +template +class Optional{ + T* data; + bool empty; + + void copy(const Optional &other); + + void move(Optional &&other) noexcept; + + void free(); + + public: + Optional(); + Optional(const T &data); + Optional(T &&data); + Optional(const Optional &other); + Optional(Optional &&other) noexcept; + Optional &operator=(const Optional &other); + Optional &operator=(Optional &&other) noexcept; + ~Optional(); + + bool has_value() const; + + T &value() &; + const T &value() const&; + T &&value() &&; + + + + T &operator*() &; + const T &operator*() const&; + T &&operator*() &&; + + const T *operator->() const; + T *operator->(); + + T value_or(const T &fallback) const; + + Optional or_else(const std::function()> &fallback) const; + + template + Optional and_then(const std::function(const T &)> &f) const; + + template + Optional transform(const std::function &f) const; +}; + +template +template +Optional Optional::transform(const std::function &f) const { + if (has_value()) + return Optional(f(value())); + else + return Optional(); +} + +template +template +Optional Optional::and_then(const std::function(const T &)> &f) const { + if (has_value()) + return f(value()); + else + return Optional(); +} + +template +void Optional::copy(const Optional &other) { + if (other.has_value()) { + empty = false; + data = new T(other.value()); + } else { + empty = true; + data = nullptr; + } +} + +template +void Optional::move(Optional &&other) noexcept { + data = other.data; + empty = other.empty; + + other.data = nullptr; + other.empty = true; +} +template +void Optional::free() { + delete data; + empty = true; +} + +template +Optional::Optional() : data(nullptr), empty(true) {} + +template +Optional::Optional(const T &data) : data(new T(data)), empty(false) {} + +template +Optional::Optional(T &&data) : data(new T(std::move(data))), empty(false) {} + +template +Optional::Optional(const Optional &other) { + copy(other); +} + +template +Optional::Optional(Optional &&other) noexcept { + move(std::move(other)); +} + +template +Optional &Optional::operator=(const Optional &other) { + if (this == &other) + return *this; + free(); + copy(other); + return *this; +} + +template +Optional& Optional::operator=(Optional &&other) noexcept { + if (this == &other) + return *this; + free(); + move(std::move(other)); + return *this; +} + +template +Optional::~Optional() { free(); } + +template +bool Optional::has_value() const { return !empty; } + +template +const T &Optional::value() const& { return *data; } + +template +T &Optional::value() & { return *data; } + +template +T &&Optional::value() && { return std::move(*data); } + +template +const T &Optional::operator*() const& { + return value(); +} + +template +T &Optional::operator*() & { + return value(); +} + +template +T &&Optional::operator*() && { + return std::move(value()); +} + +template +const T *Optional::operator->() const { + return data; +} + +template +T *Optional::operator->() { return data; } + +template +T Optional::value_or(const T &fallback) const { + if (has_value()) + return value(); + else + return fallback; +} + +template +Optional Optional::or_else(const std::function()> &fallback) const { + if (has_value()) + return *this; + else + return fallback(); +}; diff --git a/2025-2026/Week 14/Solutions/include/Vector.hpp b/2025-2026/Week 14/Solutions/include/Vector.hpp new file mode 100644 index 0000000..98a2f4a --- /dev/null +++ b/2025-2026/Week 14/Solutions/include/Vector.hpp @@ -0,0 +1,115 @@ +#pragma once + +#include +#include +#include + +template +class Vector { + T* arr; + size_t m_size; + size_t m_capacity; + + void free(){ + delete arr; + m_size = 0; + m_capacity = 0; + } + + void copy(const Vector& other){ + arr = new T[other.m_capacity]; + m_capacity = other.m_capacity; + m_size = other.m_size; + + for(size_t i = 0 ; i < m_size; i++){ + arr[i] = other.arr[i]; + } + } + + void move(Vector&& other) noexcept { + arr = other.arr; + m_size = other.m_size; + m_capacity = other.m_capacity; + + other.arr = nullptr; + other.m_size = 0; + other.m_capacity = 0; + } + + void resize() { + if(m_capacity == 0) m_capacity = 2; + m_capacity *= 2; + T* newArr = new T[m_capacity]; + for(int i = 0; i < m_size ; i++){ + newArr[i] = arr[i]; + } + delete[] arr; + arr = newArr; + } + +public: + Vector() : arr(nullptr), m_size(0), m_capacity(0) {} + Vector(const std::vector& vec) : Vector(){ + for(const T& el : vec){ + push_back(el); + } + } + Vector(const Vector& other) { + copy(other); + } + Vector(Vector&& other) noexcept{ + move(std::move(other)); + } + Vector& operator=(const Vector& other) { + if(this != &other){ + free(); + copy(other); + } + return *this; + } + Vector& operator=(Vector&& other) noexcept { + if(this != &other){ + free(); + move(std::move(other)); + } + return *this; + } + ~Vector(){ + free(); + } + + bool empty() const { + return m_size == 0; + } + + size_t size() const { + return m_size; + } + + size_t capacity() const { + return m_capacity; + } + + T& operator[](size_t index) { + return arr[index]; + } + + const T& operator[](size_t index) const { + return arr[index]; + } + + void push_back(const T& el){ + if(m_size >= m_capacity){ + resize(); + } + arr[m_size++] = el; + } + + void push_back(T&& el) { + if(m_size >= m_capacity){ + resize(); + } + arr[m_size++] = std::move(el); + } + +}; diff --git a/2025-2026/Week 14/Solutions/src/main.cpp b/2025-2026/Week 14/Solutions/src/main.cpp new file mode 100644 index 0000000..bc8f460 --- /dev/null +++ b/2025-2026/Week 14/Solutions/src/main.cpp @@ -0,0 +1,6 @@ +#include + +int main() { + std::cout << "Hello, World!" << std::endl; + return 0; +} diff --git a/2025-2026/Week 14/Solutions/test/EitherTests.cpp b/2025-2026/Week 14/Solutions/test/EitherTests.cpp new file mode 100644 index 0000000..106d95f --- /dev/null +++ b/2025-2026/Week 14/Solutions/test/EitherTests.cpp @@ -0,0 +1,218 @@ +#include "Vector.hpp" +#include "doctest.h" +#include "Either.hpp" +#include +#include +#include + +TEST_CASE("Either - Create"){ + SUBCASE("Left Value"){ + SUBCASE("Move Value"){ + Either a(5); + REQUIRE(a.is_left()); + CHECK_EQ(a.left(), 5); + } + SUBCASE("Copy Value"){ + int num = 5; + Either a(num); + REQUIRE(a.is_left()); + CHECK_EQ(a.left(), 5); + } + + } + SUBCASE("Right Value"){ + SUBCASE("Move Value"){ + Either a('a'); + REQUIRE(a.is_right()); + CHECK_EQ(a.right(), 'a'); + } + SUBCASE("Copy Value"){ + char c = 'a'; + Either a(c); + REQUIRE(a.is_right()); + CHECK_EQ(a.right(), 'a'); + } + } +} + +TEST_CASE("Either - Copy"){ + SUBCASE("Left"){ + Either a(42); + SUBCASE("Copy Constructor"){ + Either b(a); + REQUIRE(b.is_left()); + CHECK_EQ(b.left(), 42); + } + SUBCASE("Copy operator="){ + Either b(2); + b = a; + REQUIRE(b.is_left()); + CHECK_EQ(b.left(), 42); + } + } + SUBCASE("Right Value"){ + Either a(true); + SUBCASE("Copy Constructor"){ + Either b(a); + REQUIRE(b.is_right()); + CHECK_EQ(b.right(), true); + } + SUBCASE("Copy operator="){ + Either b(2); + b = a; + REQUIRE(b.is_right()); + CHECK_EQ(b.right(), true); + } + } +} + +TEST_CASE("Either - Move"){ + SUBCASE("Left Value"){ + Either a(42); + SUBCASE("Move Constructor"){ + Either b(std::move(a)); + REQUIRE(b.is_left()); + CHECK_EQ(b.left(), 42); + } + SUBCASE("Move operator="){ + Either b(2); + b = std::move(a); + REQUIRE(b.is_left()); + CHECK_EQ(b.left(), 42); + } + } + SUBCASE("Right Value"){ + Either a(true); + SUBCASE("Move Constructor"){ + Either b(std::move(a)); + REQUIRE(b.is_right()); + CHECK_EQ(b.right(), true); + } + SUBCASE("Move operator="){ + Either b(2); + b = std::move(a); + REQUIRE(b.is_right()); + CHECK_EQ(b.right(), true); + } + } +} +template +bool operator==(const Vector& lhs, const Vector& rhs){ + if(lhs.size() != rhs.size()) return false; + for(size_t i = 0; i < lhs.size(); i++){ + if(lhs[i]!=rhs[i]) return false; + } + return true; +} + +TEST_CASE("Either - left"){ + Vector vec({1,2,3,4,5}); + Either, bool> either(vec); + CHECK_EQ(vec, either.left()); + CHECK_NOTHROW(either.left()[0] = 2); + CHECK_EQ(either.left()[0], 2); + + Vector vec2(std::move(either).left()); + CHECK(either.left().empty()); +} + +TEST_CASE("Either - right"){ + Vector vec({1,2,3,4,5}); + Either> either(vec); + CHECK_EQ(vec, either.right()); + CHECK_NOTHROW(either.right()[0] = 2); + CHECK_EQ(either.right()[0], 2); + + Vector vec2(std::move(either).right()); + CHECK(either.right().empty()); +} + +TEST_CASE("Either - and_then"){ + Either either(5); + SUBCASE("Left Value"){ + + } + SUBCASE("Right Value"){ + either = false; + } + + Either result = either.and_then([](int n){return Either(n/2.0);}); + + if(either.is_left()){ + CHECK_EQ(result.left(), either.left()/2.0); + } + else{ + CHECK_FALSE(result.right()); + } +} + +TEST_CASE("Either - transform_left"){ + Either either(11); + SUBCASE("Left Value"){ + + } + SUBCASE("Right Value"){ + either = true; + } + + Either result = either.transform_left([](int n){return n/2.0;}); + if(either.is_left()){ + CHECK_EQ(result.left(), either.left()/2.0); + } + else{ + CHECK(result.right()); + } +} + +TEST_CASE("Either - transform_right"){ + Either either(11); + SUBCASE("Left Value"){ + either = true; + } + SUBCASE("Right Value"){ + + } + + Either result = either.transform_right([](int n){return n/2.0;}); + if(!either.is_left()){ + CHECK_EQ(result.right(), either.right()/2.0); + } + else{ + CHECK(result.left()); + } +} + + +int functionThatCanThrow(int n){ + if(n%2 == 0) return n/2; + else throw std::runtime_error("n is not divisible by 2"); +} + +Either divideBy2IfEven(int n){ + try{ + return functionThatCanThrow(n); + } + catch(const std::runtime_error& e){ + return e; + } +} + +TEST_CASE("Either Example"){ + Vector nums; + + for(int i = 0; i < 10; i++){ + Either result = + divideBy2IfEven(i) + .and_then([](int n){return n+1;}) + .visit([&nums](int n){nums.push_back(n); return n;}, + [](const std::exception& e){return e.what();}); + + if(result.is_left()){ + CHECK_EQ(result.left(), i/2 + 1); + } + else{ + CHECK_EQ(result.right(), "n is not divisible by 2"); + } + } + CHECK_EQ(nums, Vector({1,2,3,4, 5})); +} diff --git a/2025-2026/Week 14/Solutions/test/OptionalTests.cpp b/2025-2026/Week 14/Solutions/test/OptionalTests.cpp new file mode 100644 index 0000000..a274282 --- /dev/null +++ b/2025-2026/Week 14/Solutions/test/OptionalTests.cpp @@ -0,0 +1,221 @@ + +#include "Optional.hpp" +#include "Vector.hpp" +#include "doctest.h" +#include +#include + +TEST_CASE("Optional - Create"){ + SUBCASE("Empty"){ + Optional a; + CHECK_FALSE(a.has_value()); + } + SUBCASE("With Value"){ + SUBCASE("Move Value"){ + Optional a(2); + REQUIRE(a.has_value()); + CHECK_EQ(a.value(), 2); + } + SUBCASE("Copy Value"){ + int num = 2; + Optional a(num); + REQUIRE(a.has_value()); + CHECK_EQ(a.value(), 2); + } + } +} + +TEST_CASE("Optional - Copy"){ + SUBCASE("Empty"){ + Optional a; + SUBCASE("Copy Constructor"){ + Optional b(a); + CHECK_FALSE(b.has_value()); + } + SUBCASE("Copy operator="){ + Optional b(2); + b = a; + CHECK_FALSE(b.has_value()); + } + } + SUBCASE("With Value"){ + Optional a(42); + SUBCASE("Copy Constructor"){ + Optional b(a); + REQUIRE(b.has_value()); + CHECK_EQ(b.value(), 42); + } + SUBCASE("Copy operator="){ + Optional b(2); + b = a; + REQUIRE(b.has_value()); + CHECK_EQ(b.value(), 42); + } + } +} + +TEST_CASE("Optional - Move"){ + SUBCASE("Empty"){ + Optional a; + SUBCASE("Move Constructor"){ + Optional b(std::move(a)); + CHECK_FALSE(b.has_value()); + CHECK_FALSE(a.has_value()); + } + SUBCASE("Move operator="){ + Optional b(2); + b = std::move(a); + CHECK_FALSE(b.has_value()); + CHECK_FALSE(a.has_value()); + } + } + SUBCASE("With Value"){ + Optional a(42); + SUBCASE("Move Constructor"){ + Optional b(std::move(a)); + REQUIRE(b.has_value()); + CHECK_EQ(b.value(), 42); + CHECK_FALSE(a.has_value()); + } + SUBCASE("Move operator="){ + Optional b(2); + b = std::move(a); + REQUIRE(b.has_value()); + CHECK_EQ(b.value(), 42); + CHECK_FALSE(a.has_value()); + } + } +} +template +bool operator==(const Vector& lhs, const Vector& rhs){ + if(lhs.size() != rhs.size()) return false; + for(size_t i = 0; i < lhs.size(); i++){ + if(lhs[i]!=rhs[i]) return false; + } + return true; +} + +TEST_CASE("Optional - value"){ + Vector vec({1,2,3,4,5}); + Optional> optional(vec); + CHECK_EQ(vec, optional.value()); + CHECK_NOTHROW(optional.value()[0] = 2); + CHECK_EQ(optional.value()[0], 2); + + Vector vec2(std::move(optional).value()); + CHECK(optional.value().empty()); +} + +TEST_CASE("Optional - value_or"){ + Optional optional; + int expected; + int fallback = 5; + SUBCASE("Empty"){ + expected = fallback; + } + SUBCASE("With Value"){ + optional = 10; + expected = 10; + } + CHECK_NOTHROW(optional.value_or(fallback)); + CHECK_EQ(optional.value_or(fallback), expected); +} + +TEST_CASE("Optional - or_else"){ + std::function()> zero = [](){return Optional(0);}; + SUBCASE("Empty"){ + Optional optional; + CHECK_EQ(optional.or_else(zero).value(), 0); + } + SUBCASE("With Value"){ + Optional optional(5); + CHECK_EQ(optional.or_else(zero).value(), 5); + } +} + +TEST_CASE("Optional - and_then"){ + Optional optional; + SUBCASE("Empty"){ + + } + SUBCASE("With Value"){ + optional = 11; + } + + Optional result = optional.and_then([](int n){return Optional(n/2.0);}); + if(optional.has_value()){ + CHECK_EQ(result.value(), optional.value()/2.0); + } + else{ + CHECK_FALSE(result.has_value()); + } +} + +TEST_CASE("Optional - transform"){ + Optional optional; + SUBCASE("Empty"){ + + } + SUBCASE("With Value"){ + optional = 11; + } + + Optional result = optional.transform([](int n){return n/2.0;}); + if(optional.has_value()){ + CHECK_EQ(result.value(), optional.value()/2.0); + } + else{ + CHECK_FALSE(result.has_value()); + } +} + +template +class Reference{ + T* ptr; +public: + Reference(T& ref) : ptr(&ref) {} + operator T&() {return *ptr;} + operator T&() const {return *ptr;} +}; + +template +Optional> dereference(T* ptr){ + if(!ptr) return {}; + else return Optional>(*ptr); +} + +TEST_CASE("Optional Example"){ + std::vector v; + for(int i = 0; i < 10; i++){ + if(i % 9 == 0){ + v.push_back(nullptr); + } + else { + v.push_back(new int(i)); + } + } + + int sum = 0; + + for(int i = 0; i < v.size(); i++){ + int oldValue; + + sum += + dereference(v[i]) + .and_then([&oldValue](int& a){ + oldValue = a; + a *= a; + return Optional(a); + }).or_else([](){ + return Optional(9); + }).value(); + + if(v[i]){ + CHECK_EQ(*v[i], oldValue * oldValue); + delete v[i]; + } + } + + CHECK_EQ(sum, 222); + +} \ No newline at end of file diff --git a/2025-2026/Week 14/Solutions/test/VectorTests.cpp b/2025-2026/Week 14/Solutions/test/VectorTests.cpp new file mode 100644 index 0000000..385ae35 --- /dev/null +++ b/2025-2026/Week 14/Solutions/test/VectorTests.cpp @@ -0,0 +1,114 @@ + +#include "doctest.h" +#include "Vector.hpp" + +TEST_CASE("Vector - Create"){ + Vector v; + CHECK(v.empty()); + CHECK_EQ(v.size(), 0); + CHECK_EQ(v.capacity(), 0); +} + +TEST_CASE("Vector - Push Back"){ + Vector v; + SUBCASE("Move"){ + v.push_back(2); + CHECK_FALSE(v.empty()); + CHECK_EQ(v.size(), 1); + CHECK_GE(v.capacity(), 1); + v.push_back(3); + CHECK_EQ(v.size(), 2); + CHECK_GE(v.capacity(), 2); + } + SUBCASE("Copy"){ + int a = 1; + int b = 2; + v.push_back(a); + CHECK_FALSE(v.empty()); + CHECK_EQ(v.size(), 1); + CHECK_GE(v.capacity(), 1); + v.push_back(b); + CHECK_EQ(v.size(), 2); + CHECK_GE(v.capacity(), 2); + } + for(int i = 0; i < 10; i++) + v.push_back(i); + CHECK_EQ(v.size(), 12); + CHECK_GE(v.capacity(), 12); +} + +TEST_CASE("Vector - operator[]"){ + Vector v; + for(int i = 0;i < 10; i++){ + v.push_back(i); + } + for(int i = 0; i < 10; i++){ + CHECK_EQ(v[i], i); + } + SUBCASE("const operator[]"){ + const Vector& v2 = v; + for(int i = 0; i < 10; i++){ + CHECK_EQ(v2[i], i); + } + } +} + +TEST_CASE("Vector - Copy"){ + Vector v; + for(int i = 1; i < 4; i++){ + v.push_back(i); + } + SUBCASE("Copy Constructor"){ + Vector copy(v); + CHECK_EQ(v.capacity(),copy.capacity()); + CHECK_EQ(v.size(), copy.size()); + for(int i = 0; i < v.size(); i++){ + CHECK_EQ(v[i], copy[i]); + v[i]++; + } + for(int i = 0; i < v.size(); i++){ + CHECK_NE(v[i], copy[i]); + } + } + SUBCASE("Copy operator="){ + Vector copy; + copy = v; + CHECK_EQ(v.capacity(),copy.capacity()); + CHECK_EQ(v.size(), copy.size()); + for(int i = 0; i < v.size(); i++){ + CHECK_EQ(v[i], copy[i]); + v[i]++; + } + for(int i = 0; i < v.size(); i++){ + CHECK_NE(v[i], copy[i]); + } + } + +} + +TEST_CASE("Vector - Move"){ + Vector v; + for(int i = 1; i < 4; i++){ + v.push_back(i); + } + Vector vCopy(v); + SUBCASE("Move Constructor"){ + Vector copy(std::move(v)); + CHECK_EQ(vCopy.capacity(),copy.capacity()); + CHECK_EQ(vCopy.size(), copy.size()); + for(int i = 0; i < vCopy.size(); i++){ + CHECK_EQ(vCopy[i], copy[i]); + } + CHECK(v.empty()); + } + SUBCASE("Move operator="){ + Vector copy; + copy = std::move(v); + CHECK_EQ(vCopy.capacity(),copy.capacity()); + CHECK_EQ(vCopy.size(), copy.size()); + for(int i = 0; i < vCopy.size(); i++){ + CHECK_EQ(vCopy[i], copy[i]); + } + CHECK(v.empty()); + } +} \ No newline at end of file diff --git a/2025-2026/Week 14/Solutions/test/test.cpp b/2025-2026/Week 14/Solutions/test/test.cpp new file mode 100644 index 0000000..114a640 --- /dev/null +++ b/2025-2026/Week 14/Solutions/test/test.cpp @@ -0,0 +1,5 @@ + +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +#include "doctest.h" + +