finish bonus 2
This commit is contained in:
@ -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)
|
||||
add_executable(subtask1 ${CMAKE_CURRENT_SOURCE_DIR}/src/subtask1.cpp)
|
||||
add_executable(subtask2 ${CMAKE_CURRENT_SOURCE_DIR}/src/subtask2.cpp)
|
@ -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
|
||||
|
@ -1,3 +1,5 @@
|
||||
#ifndef SJTU_MAP_SUBTASK1_HPP
|
||||
#define SJTU_MAP_SUBTASK1_HPP
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
@ -29,4 +31,5 @@ void my_sort(_Iter __first, _Iter __last) {
|
||||
static_assert(sjtu::is_iterator_v<_Iter>, "Not an iterator.");
|
||||
}
|
||||
|
||||
} // namespace sjtu
|
||||
} // namespace sjtu
|
||||
#endif
|
37
map/src/subtask2.cpp
Normal file
37
map/src/subtask2.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "subtask2.hpp"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#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<<std::endl;
|
||||
std::vector<int> a = {1, 2, 3, 4, 5};
|
||||
sjtu::print(a);
|
||||
std::cout << std::endl;
|
||||
std::vector<std::vector<int>> b = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
|
||||
sjtu::print(b);
|
||||
std::cout<<std::endl;
|
||||
sjtu::vector<int> c;
|
||||
c.push_back(1);
|
||||
c.push_back(2);
|
||||
c.push_back(3);
|
||||
sjtu::print(c);
|
||||
std::cout<<std::endl;
|
||||
std::map<int, std::string> d;
|
||||
d[1] = "Hello";
|
||||
d[2] = "World";
|
||||
sjtu::print(d);
|
||||
std::cout<<std::endl;
|
||||
sjtu::map<int, std::string> e;
|
||||
e[1] = "Hello";
|
||||
e[2] = "World";
|
||||
sjtu::print(e);
|
||||
std::cout<<std::endl;
|
||||
int f[3][3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
|
||||
sjtu::print(f);
|
||||
return 0;
|
||||
}
|
67
map/src/subtask2.hpp
Normal file
67
map/src/subtask2.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef SJTU_MAP_SUBTASK2_HPP
|
||||
#define SJTU_MAP_SUBTASK2_HPP
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
#include "utility.hpp"
|
||||
namespace sjtu {
|
||||
template <typename _Tp>
|
||||
static constexpr bool can_be_used_in_cout_v = requires(std::ostream &os, const _Tp &dat) {
|
||||
os << dat;
|
||||
};
|
||||
template <typename _Tp>
|
||||
static constexpr bool is_pair_v = false;
|
||||
template <typename _T1, typename _T2>
|
||||
static constexpr bool is_pair_v<std::pair<_T1, _T2> > = true;
|
||||
template <typename _T1, typename _T2>
|
||||
static constexpr bool is_pair_v<sjtu::pair<_T1, _T2> > = true;
|
||||
template <typename _Tp>
|
||||
static constexpr bool is_container_v = requires(const _Tp &x) {
|
||||
std::begin(x);
|
||||
std::end(x);
|
||||
};
|
||||
template <typename _Tp>
|
||||
static constexpr bool is_container_s_container_v = requires(const _Tp &x) {
|
||||
std::begin(*std::begin(x));
|
||||
std::end(*std::begin(x));
|
||||
};
|
||||
template <typename _Tp>
|
||||
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
|
Reference in New Issue
Block a user