From c4c2a83252906fc6d6c84689ecc345e410025767 Mon Sep 17 00:00:00 2001 From: ZhuangYumin Date: Sun, 25 Feb 2024 16:12:54 +0000 Subject: [PATCH] fix compile error --- CMakeLists.txt | 1 + vector/CMakeLists.txt | 24 +++++++++++- vector/data/two/code.cpp | 2 +- vector/src/vector.hpp | 83 +++++++++++++++++++++++++++++----------- 4 files changed, 85 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f45e64a..d8748a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.10) Project(STLite-ACM-2024) include(CTest) +set(CMAKE_CXX_STANDARD 20) add_subdirectory(vector) enable_testing() \ No newline at end of file diff --git a/vector/CMakeLists.txt b/vector/CMakeLists.txt index 3e1e4c4..db28f81 100644 --- a/vector/CMakeLists.txt +++ b/vector/CMakeLists.txt @@ -1,4 +1,26 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/data) add_executable(one ${CMAKE_CURRENT_SOURCE_DIR}/data/one/code.cpp) +add_executable(one_mem ${CMAKE_CURRENT_SOURCE_DIR}/data/one.memcheck/code.cpp) +add_executable(two ${CMAKE_CURRENT_SOURCE_DIR}/data/two/code.cpp) +add_executable(two_mem ${CMAKE_CURRENT_SOURCE_DIR}/data/two.memcheck/code.cpp) +add_executable(three ${CMAKE_CURRENT_SOURCE_DIR}/data/three/code.cpp) +add_executable(three_mem ${CMAKE_CURRENT_SOURCE_DIR}/data/three.memcheck/code.cpp) +add_executable(four ${CMAKE_CURRENT_SOURCE_DIR}/data/four/code.cpp) +add_executable(four_mem ${CMAKE_CURRENT_SOURCE_DIR}/data/four.memcheck/code.cpp) add_test(NAME vector_one COMMAND one >/tmp/one_out.txt - && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/one/answer.txt /tmp/one_out.txt>/tmp/one_diff.txt) \ No newline at end of file + && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/one/answer.txt /tmp/one_out.txt>/tmp/one_diff.txt) +add_test(NAME vector_one_mem COMMAND one_mem >/tmp/one_mem_out.txt + && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/one.memcheck/answer.txt /tmp/one_mem_out.txt>/tmp/one_mem_diff.txt) +add_test(NAME vector_two COMMAND two >/tmp/two_out.txt + && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/two/answer.txt /tmp/two_out.txt>/tmp/two_diff.txt) +add_test(NAME vector_two_mem COMMAND two_mem >/tmp/two_mem_out.txt + && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/two.memcheck/answer.txt /tmp/two_mem_out.txt>/tmp/two_mem_diff.txt) +add_test(NAME vector_three COMMAND three >/tmp/three_out.txt + && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/three/answer.txt /tmp/three_out.txt>/tmp/three_diff.txt) +add_test(NAME vector_three_mem COMMAND three_mem >/tmp/three_mem_out.txt + && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/three.memcheck/answer.txt /tmp/three_mem_out.txt>/tmp/three_mem_diff.txt) +add_test(NAME vector_four COMMAND four >/tmp/four_out.txt + && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/four/answer.txt /tmp/four_out.txt>/tmp/four_diff.txt) +add_test(NAME vector_four_mem COMMAND four_mem >/tmp/four_mem_out.txt + && diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/four.memcheck/answer.txt /tmp/four_mem_out.txt>/tmp/four_mem_diff.txt) \ No newline at end of file diff --git a/vector/data/two/code.cpp b/vector/data/two/code.cpp index 68d2ffa..0bf7002 100644 --- a/vector/data/two/code.cpp +++ b/vector/data/two/code.cpp @@ -6,7 +6,7 @@ int main() { - sjtu::vector v; + std::vector v; for (long long i = 0; i < 1LL << 20; ++i) { v.push_back(i); } diff --git a/vector/src/vector.hpp b/vector/src/vector.hpp index 6b30786..769aaf7 100644 --- a/vector/src/vector.hpp +++ b/vector/src/vector.hpp @@ -235,7 +235,7 @@ class vector { allocated_length = other.allocated_length; current_length = other.current_length; for (size_t i = 0; i < current_length; ++i) { - alloc.construct(raw_beg + i, other.raw_beg[i]); + std::allocator_traits::construct(alloc, raw_beg + i, other.raw_beg[i]); } } vector(vector &&other) noexcept { @@ -251,7 +251,7 @@ class vector { ~vector() { if (raw_beg != nullptr) { for (size_t i = 0; i < current_length; ++i) { - alloc.destroy(raw_beg + i); + std::allocator_traits::destroy(alloc, raw_beg + i); } alloc.deallocate(raw_beg, allocated_length); } @@ -263,7 +263,7 @@ class vector { if (this == &other) return *this; if (raw_beg != nullptr) { for (size_t i = 0; i < current_length; ++i) { - alloc.destroy(raw_beg + i); + std::allocator_traits::destroy(alloc, raw_beg + i); } alloc.deallocate(raw_beg, allocated_length); } @@ -272,7 +272,7 @@ class vector { allocated_length = other.allocated_length; current_length = other.current_length; for (size_t i = 0; i < current_length; ++i) { - alloc.construct(raw_beg + i, other.raw_beg[i]); + std::allocator_traits::construct(alloc, raw_beg + i, other.raw_beg[i]); } return *this; } @@ -358,20 +358,21 @@ class vector { if (current_length == allocated_length) { size_t new_allocated_length = allocated_length * 2; T *new_raw_beg = alloc.allocate(new_allocated_length); + pos.raw_pointer = new_raw_beg + (pos.raw_pointer - raw_beg); for (size_t i = 0; i < current_length; ++i) { - alloc.construct(new_raw_beg + i, std::move(raw_beg[i])); - alloc.destroy(raw_beg + i); + std::allocator_traits::construct(alloc, new_raw_beg + i, std::move(raw_beg[i])); + std::allocator_traits::destroy(alloc, raw_beg + i); } alloc.deallocate(raw_beg, allocated_length); raw_beg = new_raw_beg; raw_end = raw_beg + current_length; allocated_length = new_allocated_length; } - for (T *i = raw_end; i != pos.raw_pointer; --i) { - alloc.construct(i, std::move(*(i - 1))); - alloc.destroy(i - 1); + for (T *i = raw_end - 1; i != pos.raw_pointer; --i) { + std::allocator_traits::construct(alloc, i, std::move(*(i - 1))); + std::allocator_traits::destroy(alloc, i - 1); } - alloc.construct(pos.raw_pointer, value); + std::allocator_traits::construct(alloc, pos.raw_pointer, value); raw_end++; current_length++; return pos; @@ -397,7 +398,7 @@ class vector { raw_end = raw_beg + current_length; allocated_length = new_allocated_length; } - for (T *i = raw_end; i != raw_beg + ind; --i) { + for (T *i = raw_end - 1; i != raw_beg + ind; --i) { alloc.construct(i, std::move(*(i - 1))); alloc.destroy(i - 1); } @@ -414,11 +415,23 @@ class vector { iterator erase(iterator pos) { if (pos.raw_pointer < raw_beg || pos.raw_pointer >= raw_end) throw invalid_iterator(); for (T *i = pos.raw_pointer; i != raw_end - 1; ++i) { - alloc.construct(i, std::move(*(i + 1))); - alloc.destroy(i + 1); + std::allocator_traits::construct(alloc, i, std::move(*(i + 1))); + std::allocator_traits::destroy(alloc, i + 1); } raw_end--; current_length--; + if (current_length != 0 && current_length <= allocated_length / 4) { + size_t new_allocated_length = allocated_length / 2; + T *new_raw_beg = alloc.allocate(new_allocated_length); + for (size_t i = 0; i < current_length; ++i) { + std::allocator_traits::construct(alloc, new_raw_beg + i, std::move(raw_beg[i])); + std::allocator_traits::destroy(alloc, raw_beg + i); + } + alloc.deallocate(raw_beg, allocated_length); + raw_beg = new_raw_beg; + raw_end = raw_beg + current_length; + allocated_length = new_allocated_length; + } return pos; } /** @@ -434,14 +447,8 @@ class vector { } raw_end--; current_length--; - return iterator(this, raw_beg + ind); - } - /** - * adds an element to the end. - */ - void push_back(const T &value) { - if (current_length == allocated_length) { - size_t new_allocated_length = allocated_length * 2; + if (current_length != 0 && current_length <= allocated_length / 4) { + size_t new_allocated_length = allocated_length / 2; T *new_raw_beg = alloc.allocate(new_allocated_length); for (size_t i = 0; i < current_length; ++i) { alloc.construct(new_raw_beg + i, std::move(raw_beg[i])); @@ -452,7 +459,25 @@ class vector { raw_end = raw_beg + current_length; allocated_length = new_allocated_length; } - alloc.construct(raw_end, value); + return iterator(this, raw_beg + ind); + } + /** + * adds an element to the end. + */ + void push_back(const T &value) { + if (current_length == allocated_length) { + size_t new_allocated_length = allocated_length * 2; + T *new_raw_beg = alloc.allocate(new_allocated_length); + for (size_t i = 0; i < current_length; ++i) { + std::allocator_traits::construct(alloc, new_raw_beg + i, std::move(raw_beg[i])); + std::allocator_traits::destroy(alloc, raw_beg + i); + } + alloc.deallocate(raw_beg, allocated_length); + raw_beg = new_raw_beg; + raw_end = raw_beg + current_length; + allocated_length = new_allocated_length; + } + std::allocator_traits::construct(alloc, raw_end, value); raw_end++; current_length++; } @@ -462,9 +487,21 @@ class vector { */ void pop_back() { if (current_length == 0) throw container_is_empty(); - alloc.destroy(raw_end - 1); + std::allocator_traits::destroy(alloc, raw_end - 1); raw_end--; current_length--; + if (current_length != 0 && current_length <= allocated_length / 4) { + size_t new_allocated_length = allocated_length / 2; + T *new_raw_beg = alloc.allocate(new_allocated_length); + for (size_t i = 0; i < current_length; ++i) { + std::allocator_traits::construct(alloc, new_raw_beg + i, std::move(raw_beg[i])); + std::allocator_traits::destroy(alloc, raw_beg + i); + } + alloc.deallocate(raw_beg, allocated_length); + raw_beg = new_raw_beg; + raw_end = raw_beg + current_length; + allocated_length = new_allocated_length; + } } };