From 126d03de1dd49ea9487c4946d86c8398f0fd32e0 Mon Sep 17 00:00:00 2001 From: winner245 Date: Sat, 19 Oct 2024 18:46:25 -0400 Subject: [PATCH 1/3] Implement vector constructor to support single-pass input iterator range --- MyTinySTL/vector.h | 12 +++++++++++- Test/vector_test.h | 10 ++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/MyTinySTL/vector.h b/MyTinySTL/vector.h index 5192761..c906930 100644 --- a/MyTinySTL/vector.h +++ b/MyTinySTL/vector.h @@ -80,7 +80,17 @@ class vector { fill_init(n, value); } template ::value, int>::type = 0> + mystl::is_exactly_input_iterator::value, int>::type = 0> + vector(Iter first, Iter last) + { + try_init(); + for (; first != last; ++first) { + emplace_back(*first); + } + } + + template ::value, int>::type = 0> vector(Iter first, Iter last) { MYSTL_DEBUG(!(last < first)); diff --git a/Test/vector_test.h b/Test/vector_test.h index 8b79ef6..b5ddb57 100644 --- a/Test/vector_test.h +++ b/Test/vector_test.h @@ -3,10 +3,11 @@ // vector test : 测试 vector 的接口与 push_back 的性能 -#include +#include #include "../MyTinySTL/vector.h" #include "test.h" +#include "stream_iterator.h" // 用于测试 input_iterator 迭代器版构造函数 namespace mystl { @@ -32,7 +33,6 @@ void vector_test() v8 = v3; v9 = std::move(v3); v10 = { 1,2,3,4,5,6,7,8,9 }; - FUN_AFTER(v1, v1.assign(8, 8)); FUN_AFTER(v1, v1.assign(a, a + 5)); FUN_AFTER(v1, v1.emplace(v1.begin(), 0)); @@ -90,6 +90,12 @@ void vector_test() FUN_AFTER(v1, v1.shrink_to_fit()); FUN_VALUE(v1.size()); FUN_VALUE(v1.capacity()); + + std::istringstream is("1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9"); + mystl::istream_iterator beg{is}, end; + mystl::vector v11{beg, end}; + COUT(v11); + PASSED; #if PERFORMANCE_TEST_ON std::cout << "[--------------------- Performance Testing ---------------------]\n"; From d496eb3985feca2c13be9b01d28e1f8f2ec24eff Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Mon, 28 Oct 2024 11:38:46 -0400 Subject: [PATCH 2/3] Use tag dispatching overloading for range_init --- MyTinySTL/vector.h | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/MyTinySTL/vector.h b/MyTinySTL/vector.h index c906930..73c1823 100644 --- a/MyTinySTL/vector.h +++ b/MyTinySTL/vector.h @@ -83,10 +83,7 @@ class vector mystl::is_exactly_input_iterator::value, int>::type = 0> vector(Iter first, Iter last) { - try_init(); - for (; first != last; ++first) { - emplace_back(*first); - } + range_init(first, last, mystl::input_iterator_tag{}); } template ilist) { - range_init(ilist.begin(), ilist.end()); + range_init(ilist.begin(), ilist.end(), mystl::forward_iterator_tag{}); } vector& operator=(const vector& rhs); @@ -298,8 +295,12 @@ class vector void init_space(size_type size, size_type cap); void fill_init(size_type n, const value_type& value); + + template + void range_init(Iter first, Iter last, input_iterator_tag); + template - void range_init(Iter first, Iter last); + void range_init(Iter first, Iter last, forward_iterator_tag); void destroy_and_recover(iterator first, iterator last, size_type n); @@ -611,7 +612,7 @@ fill_init(size_type n, const value_type& value) template template void vector:: -range_init(Iter first, Iter last) +range_init(Iter first, Iter last, mystl::forward_iterator_tag) { const size_type len = mystl::distance(first, last); const size_type init_size = mystl::max(len, static_cast(16)); @@ -619,6 +620,17 @@ range_init(Iter first, Iter last) mystl::uninitialized_copy(first, last, begin_); } +template +template +void vector:: +range_init(Iter first, Iter last, mystl::input_iterator_tag) +{ + try_init(); + for (; first != last; ++first) { + emplace_back(*first); + } +} + // destroy_and_recover 函数 template void vector:: From e59c010b96e8d332b2f7961993c14a34b9c4f7f7 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Mon, 28 Oct 2024 12:05:47 -0400 Subject: [PATCH 3/3] Simplify a bit by tag dispatching inside range ctor --- MyTinySTL/vector.h | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/MyTinySTL/vector.h b/MyTinySTL/vector.h index 73c1823..bd5f5c0 100644 --- a/MyTinySTL/vector.h +++ b/MyTinySTL/vector.h @@ -78,16 +78,9 @@ class vector vector(size_type n, const value_type& value) { fill_init(n, value); } - - template ::value, int>::type = 0> - vector(Iter first, Iter last) - { - range_init(first, last, mystl::input_iterator_tag{}); - } - + template ::value, int>::type = 0> + mystl::is_input_iterator::value, int>::type = 0> vector(Iter first, Iter last) { MYSTL_DEBUG(!(last < first));