diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt index ec37679..203fc8f 100644 --- a/map/CMakeLists.txt +++ b/map/CMakeLists.txt @@ -31,4 +31,5 @@ add_test(NAME mp_five COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_five >/tmp/f 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.memcheck/answer.txt /tmp/five_mem_out.txt>/tmp/five_mem_diff.txt") add_subdirectory(test) -add_executable(subtask1 ${CMAKE_CURRENT_SOURCE_DIR}/src/subtask1.cpp) \ No newline at end of file +add_executable(subtask1 ${CMAKE_CURRENT_SOURCE_DIR}/src/subtask1.cpp) +add_executable(subtask2 ${CMAKE_CURRENT_SOURCE_DIR}/src/subtask2.cpp) \ No newline at end of file diff --git a/map/src/map.hpp b/map/src/map.hpp index 43c5eb1..59366a0 100644 --- a/map/src/map.hpp +++ b/map/src/map.hpp @@ -653,6 +653,7 @@ class map { while (tmp->left != nullptr) tmp = tmp->left; return iterator(tmp, this); } + const_iterator begin() const { return cbegin(); } const_iterator cbegin() const { if (tree_root == nullptr) return const_iterator(nullptr, this); RedBlackTreeNodeType *tmp = tree_root; @@ -664,6 +665,7 @@ class map { * in fact, it returns past-the-end. */ iterator end() { return iterator(nullptr, this); } + const_iterator end() const { return cend(); } const_iterator cend() const { return const_iterator(nullptr, this); } /** * checks whether the container is empty diff --git a/map/src/subtask1.hpp b/map/src/subtask1.hpp index c79e92e..bddc45b 100644 --- a/map/src/subtask1.hpp +++ b/map/src/subtask1.hpp @@ -1,3 +1,5 @@ +#ifndef SJTU_MAP_SUBTASK1_HPP +#define SJTU_MAP_SUBTASK1_HPP #include #include #include @@ -29,4 +31,5 @@ void my_sort(_Iter __first, _Iter __last) { static_assert(sjtu::is_iterator_v<_Iter>, "Not an iterator."); } -} // namespace sjtu \ No newline at end of file +} // namespace sjtu +#endif \ No newline at end of file diff --git a/map/src/subtask2.cpp b/map/src/subtask2.cpp new file mode 100644 index 0000000..860475b --- /dev/null +++ b/map/src/subtask2.cpp @@ -0,0 +1,37 @@ +#include "subtask2.hpp" +#include +#include +#include +#include +#include "../../vector/src/vector.hpp" +#include "map.hpp" +int main() { + int v[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + sjtu::print(v); + std::cout< a = {1, 2, 3, 4, 5}; + sjtu::print(a); + std::cout << std::endl; + std::vector> b = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + sjtu::print(b); + std::cout< c; + c.push_back(1); + c.push_back(2); + c.push_back(3); + sjtu::print(c); + std::cout< d; + d[1] = "Hello"; + d[2] = "World"; + sjtu::print(d); + std::cout< e; + e[1] = "Hello"; + e[2] = "World"; + sjtu::print(e); + std::cout< +#include +#include "utility.hpp" +namespace sjtu { +template +static constexpr bool can_be_used_in_cout_v = requires(std::ostream &os, const _Tp &dat) { + os << dat; +}; +template +static constexpr bool is_pair_v = false; +template +static constexpr bool is_pair_v > = true; +template +static constexpr bool is_pair_v > = true; +template +static constexpr bool is_container_v = requires(const _Tp &x) { + std::begin(x); + std::end(x); +}; +template +static constexpr bool is_container_s_container_v = requires(const _Tp &x) { + std::begin(*std::begin(x)); + std::end(*std::begin(x)); +}; +template +void print(const _Tp &dat, size_t indent_length = 0) { + static constexpr bool need_indent = sjtu::is_container_s_container_v<_Tp>; + if constexpr (sjtu::can_be_used_in_cout_v<_Tp>) { + if constexpr (std::is_bounded_array_v<_Tp>) { + for (size_t i = 0; i < indent_length; i++) std::cout << ' '; + std::cout << '['; + if constexpr (need_indent) std::cout << '\n'; + for (size_t i = 0; i < std::extent_v<_Tp>; i++) { + if (need_indent == false && i) std::cout << ' '; + print(dat[i], indent_length + 1); + if constexpr (need_indent) std::cout << '\n'; + } + if constexpr (need_indent) + for (size_t i = 0; i < indent_length; i++) std::cout << ' '; + std::cout << ']'; + } else + std::cout << dat; + } else if constexpr (sjtu::is_container_v<_Tp>) { + for (size_t i = 0; i < indent_length; i++) std::cout << ' '; + std::cout << '['; + if constexpr (need_indent) std::cout << '\n'; + for (auto it = std::begin(dat); it != std::end(dat); it++) { + if (need_indent == false && it != std::begin(dat)) std::cout << ' '; + print(*it, indent_length + 1); + if constexpr (need_indent) std::cout << '\n'; + } + if constexpr (need_indent) + for (size_t i = 0; i < indent_length; i++) std::cout << ' '; + std::cout << ']'; + } else if constexpr (sjtu::is_pair_v<_Tp>) { + std::cout << '('; + print(dat.first, indent_length); + std::cout << ','; + print(dat.second, indent_length); + std::cout << ')'; + } else + static_assert(sjtu::can_be_used_in_cout_v<_Tp>, "Cannot print this type."); +} +} // namespace sjtu +#endif \ No newline at end of file diff --git a/vector/src/vector.hpp b/vector/src/vector.hpp index 932914d..be66fbf 100644 --- a/vector/src/vector.hpp +++ b/vector/src/vector.hpp @@ -348,11 +348,13 @@ class vector { * returns an iterator to the beginning. */ iterator begin() { return iterator(this, raw_beg); } + const_iterator begin() const { return const_iterator(this, raw_beg); } const_iterator cbegin() const { return const_iterator(this, raw_beg); } /** * returns an iterator to the end. */ iterator end() { return iterator(this, raw_end); } + const_iterator end() const { return const_iterator(this, raw_end); } const_iterator cend() const { return const_iterator(this, raw_end); } /** * checks whether the container is empty