diff --git a/CMakeLists.txt b/CMakeLists.txt index 76e6a07..9e34115 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,13 @@ include(CTest) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -fsanitize=address") +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip +) +FetchContent_MakeAvailable(googletest) +include(GoogleTest) add_subdirectory(vector) add_subdirectory(priority_queue) add_subdirectory(map) diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt index fba5e91..83e4d26 100644 --- a/map/CMakeLists.txt +++ b/map/CMakeLists.txt @@ -29,4 +29,5 @@ add_test(NAME mp_four_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_four_mem add_test(NAME mp_five COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_five >/tmp/five_out.txt\ && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/five/answer.txt /tmp/five_out.txt>/tmp/five_diff.txt") add_test(NAME mp_five_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_five_mem >/tmp/five_mem_out.txt\ - && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/five/answer.txt /tmp/five_mem_out.txt>/tmp/five_mem_diff.txt") \ No newline at end of file + && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/five/answer.txt /tmp/five_mem_out.txt>/tmp/five_mem_diff.txt") +add_subdirectory(test) \ No newline at end of file diff --git a/map/src/map.hpp b/map/src/map.hpp index f2504e2..44cebf2 100644 --- a/map/src/map.hpp +++ b/map/src/map.hpp @@ -243,7 +243,15 @@ class map { map *domain; public: + // Add some type traits + typedef std::bidirectional_iterator_tag iterator_category; + typedef pair value_type; + typedef std::ptrdiff_t difference_type; + typedef value_type *pointer; + typedef value_type &reference; + friend const_iterator; + friend map; iterator() : raw_pointer(nullptr), domain(nullptr) {} iterator(const iterator &other) : raw_pointer(other.raw_pointer), domain(other.domain) {} iterator(RedBlackTreeNodeType *raw_pointer, map *domain) : raw_pointer(raw_pointer), domain(domain) {} @@ -326,7 +334,15 @@ class map { const map *domain; public: + // Add some type traits + typedef std::bidirectional_iterator_tag iterator_category; + typedef pair value_type; + typedef std::ptrdiff_t difference_type; + typedef value_type *pointer; + typedef value_type &reference; + friend iterator; + friend map; const_iterator() : raw_pointer(nullptr), domain(nullptr) {} const_iterator(const const_iterator &other) : raw_pointer(other.raw_pointer), domain(other.domain) {} const_iterator(const iterator &other) : raw_pointer(other.raw_pointer), domain(other.domain) {} @@ -409,7 +425,7 @@ class map { other.tree_root = nullptr; } /** - * TODO assignment operator + * assignment operator */ map &operator=(const map &other) { if (this == &other) return *this; @@ -417,6 +433,7 @@ class map { delete tree_root; node_count = other.node_count; CopyFrom(tree_root, other.tree_root); + return *this; } map &operator=(map &&other) { if (this == &other) return *this; @@ -426,6 +443,7 @@ class map { tree_root = other.tree_root; other.node_count = 0; other.tree_root = nullptr; + return *this; } ~map() { if (tree_root) tree_root->ReleaseAll(); @@ -447,7 +465,6 @@ class map { return result->val.second; } /** - * TODO * access specified element * Returns a reference to the value that is mapped to a key equivalent to key, * performing an insertion if such key does not already exist. @@ -521,7 +538,9 @@ class map { * * throw if pos pointed to a bad element (pos == this->end() || pos points an element out of this) */ - void erase(iterator pos) {} + void erase(iterator pos) { + if (pos.domain != this || pos.raw_pointer == nullptr) throw invalid_iterator(); + } /** * Returns the number of elements with key * that compares equivalent to the specified argument, diff --git a/map/test/CMakeLists.txt b/map/test/CMakeLists.txt new file mode 100644 index 0000000..3fa8324 --- /dev/null +++ b/map/test/CMakeLists.txt @@ -0,0 +1,9 @@ +add_executable( + test_mp_basic + test_basic.cpp +) +target_link_libraries( + test_mp_basic + GTest::gtest_main +) +gtest_discover_tests(test_mp_basic) \ No newline at end of file diff --git a/map/test/test_basic.cpp b/map/test/test_basic.cpp new file mode 100644 index 0000000..d07353b --- /dev/null +++ b/map/test/test_basic.cpp @@ -0,0 +1,15 @@ +#include +#include "map.hpp" + +TEST(BasicTests, GTestItSelf) { + // Expect two strings not to be equal. + EXPECT_STRNE("hello", "world"); + // Expect equality. + EXPECT_EQ(7 * 6, 42); +} + +TEST(BasicTests, ConstructorAndEmptySize) { + sjtu::map map; + EXPECT_EQ(map.empty(), true); + EXPECT_EQ(map.size(), 0); +} \ No newline at end of file