diff --git a/homework/unique_ptr/CMakeLists.txt b/homework/unique_ptr/CMakeLists.txt new file mode 100644 index 00000000..e226697f --- /dev/null +++ b/homework/unique_ptr/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.11.0) +project(unique_ptr) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include(FetchContent) +FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG main +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_executable(${PROJECT_NAME}_tests ${PROJECT_NAME}_tests.cpp) + +target_link_libraries(${PROJECT_NAME}_tests gtest_main) + +include(GoogleTest) +gtest_discover_tests(${PROJECT_NAME}_tests) diff --git a/homework/unique_ptr/build.bat b/homework/unique_ptr/build.bat new file mode 100644 index 00000000..0d447811 --- /dev/null +++ b/homework/unique_ptr/build.bat @@ -0,0 +1,10 @@ +RMDIR build /S /Q +mkdir build +cd build +cmake -G "MinGW Makefiles" .. +MinGW32-make + +unique_ptr_tests.exe + +cd .. + diff --git a/homework/unique_ptr/format.bat b/homework/unique_ptr/format.bat new file mode 100644 index 00000000..5e62c1ff --- /dev/null +++ b/homework/unique_ptr/format.bat @@ -0,0 +1 @@ +clang-format --style=file -i *.hpp *.cpp \ No newline at end of file diff --git a/homework/unique_ptr/unique_ptr.hpp b/homework/unique_ptr/unique_ptr.hpp new file mode 100644 index 00000000..d4eea5ab --- /dev/null +++ b/homework/unique_ptr/unique_ptr.hpp @@ -0,0 +1,58 @@ +#pragma once + +namespace my { + +template +class unique_ptr { +private: + T* ptr; + +public: + // Constructor + unique_ptr(T* p = nullptr) { + ptr = p; + } + // Copy constructor + unique_ptr(unique_ptr& other) = delete; + // Move constructor + unique_ptr(unique_ptr&& other) { + ptr = other.ptr; + other.ptr = nullptr; + } + // Copy assignment + unique_ptr& operator=(unique_ptr& other) = delete; + // Move assignment + unique_ptr& operator=(unique_ptr&& other) { + if (this != &other) { + delete ptr; + ptr = other.ptr; + other.ptr = nullptr; + } + return *this; + } + // Destructor + ~unique_ptr() { + delete ptr; + } + + T& operator*() { + return *ptr; + } + T* operator->() { + return ptr; + } + T* get() { + return ptr; + } + T* release() { + T* temp_ptr = ptr; + ptr = nullptr; + return temp_ptr; + } + void reset(T* new_obj = nullptr) { + delete ptr; + ptr = new_obj; + } +}; + +} // namespace my diff --git a/homework/unique_ptr/unique_ptr_tests.cpp b/homework/unique_ptr/unique_ptr_tests.cpp new file mode 100644 index 00000000..ada62f7c --- /dev/null +++ b/homework/unique_ptr/unique_ptr_tests.cpp @@ -0,0 +1,62 @@ +#include +#include "unique_ptr.hpp" + +template class my::unique_ptr; + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +TEST(UniquePtrTest, ConstructorDereference) { + my::unique_ptr ptr(new int(5)); + EXPECT_EQ(*ptr, 5); +} + +TEST(UniquePtrTest, MoveConstructor) { + my::unique_ptr ptr1(new int(5)); + my::unique_ptr ptr2(std::move(ptr1)); + EXPECT_EQ(*ptr2, 5); + EXPECT_EQ(ptr1.get(), nullptr); +} + +TEST(UniquePtrTest, MoveAssignmentOperator) { + my::unique_ptr ptr1(new int(5)); + my::unique_ptr ptr2(new int(15)); + ptr2 = std::move(ptr1); + + EXPECT_EQ(ptr1.get(), nullptr); + EXPECT_EQ(*ptr2, 5); +} + +TEST(UniquePtrTest, ArrowOperator) { + struct Foo { + int give5() { return 5; } + }; + my::unique_ptr ptr(new Foo); + EXPECT_EQ(ptr->give5(), 5); +} + +TEST(UniquePtrTest, GetTest) { + my::unique_ptr ptr1(new int(10)); + int* ptr1_int = ptr1.get(); + + EXPECT_EQ(*ptr1_int, 10); +} + +TEST(UniquePtrTest, ReleaseTest) { + my::unique_ptr ptr1(new int(10)); + int* ptr1_int = ptr1.release(); + + EXPECT_EQ(*ptr1_int, 10); + EXPECT_EQ(ptr1.get(), nullptr); + delete ptr1_int; +} + +TEST(UniquePtrTest, ResetTest) { + my::unique_ptr ptr1(new int(10)); + EXPECT_EQ(*ptr1, 10); + + ptr1.reset(new int(20)); + EXPECT_EQ(*ptr1, 20); +} \ No newline at end of file