From add41d9c0620c3f1665396a895515e8b37a363b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=99=93=E8=88=AA?= <1210603696@qq.com> Date: Mon, 22 Sep 2014 14:07:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90vector=E5=AE=B9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TinySTL/Vector.h | 106 ++++++++++++++++++++++++++++++++++++++++------- TinySTL/main.cpp | 22 +++++++++- 2 files changed, 111 insertions(+), 17 deletions(-) diff --git a/TinySTL/Vector.h b/TinySTL/Vector.h index 412c8ee..6f86440 100644 --- a/TinySTL/Vector.h +++ b/TinySTL/Vector.h @@ -1,6 +1,8 @@ #ifndef _VECTOR_H_ #define _VECTOR_H_ +#include +#include #include #include "Allocator.h" @@ -11,7 +13,7 @@ namespace TinySTL{ namespace { template - class viter: public iterator, T>{ + class viter : public TinySTL::iterator{ private: T * ptr_; private: @@ -22,6 +24,8 @@ namespace TinySTL{ viter(const viter& vit); viter& operator = (const viter& vit); + operator void* (){ return ptr_; }//change to the primitive pointer type + T& operator *(){ return *ptr_; } T *operator ->(){ return &(operator *()); } @@ -69,6 +73,7 @@ namespace TinySTL{ } }// end of anonymous namespace + //********* vector ************* template> class vector{ private: @@ -79,12 +84,12 @@ namespace TinySTL{ typedef Alloc dataAllocator; //Alloc dataAllocator; public: - typedef T value_type; - typedef viter iterator; - typedef iterator pointer; - typedef T& reference; - typedef size_t size_type; - typedef typename iterator::difference_type difference_type; + typedef T value_type; + typedef viter iterator; + typedef iterator pointer; + typedef T& reference; + typedef size_t size_type; + typedef typename iterator::difference_type difference_type; public: //构造,复制,析构相关函数 vector() @@ -97,8 +102,7 @@ namespace TinySTL{ vector(vector&& v); vector& operator = (const vector& v); ~vector(){ - dataAllocator::destroy(start_, finish_); - dataAllocator::deallocate(start_, endOfStorage_ - start_); + destroyAndDeallocateAll(); } //迭代器相关 @@ -129,26 +133,27 @@ namespace TinySTL{ std::swap(endOfStorage_, v.endOfStorage_); } } - //TODO void push_back(const value_type& value); void pop_back(){ --finish_; dataAllocator::destroy(finish_); } - //TODO iterator insert(iterator position, const value_type& val); - //TODO - void insert(iterator position, size_type n, const value_type& val); - //TODO + void insert(iterator position, const size_type& n, const value_type& val); template void insert(iterator position, InputIterator first, InputIterator last); - //TODO iterator erase(iterator position); iterator erase(iterator first, iterator last); //容器的空间配置器相关 Alloc get_allocator(){ return dataAllocator; } private: + void destroyAndDeallocateAll(){ + if (capacity() != 0){ + dataAllocator::destroy(start_, finish_); + dataAllocator::deallocate(start_, endOfStorage_ - start_); + } + } void allocateAndFillN(const size_type n, const value_type& value){ start_ = dataAllocator::allocate(n); TinySTL::uninitialized_fill_n(start_, n, value); @@ -169,7 +174,15 @@ namespace TinySTL{ void vector_aux(Integer n, Integer value, std::true_type){ allocateAndFillN(n, value); } - }; + template + void insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type); + template + void insert_aux(iterator position, Integer n, Integer value, std::true_type); + template + void reallocateAndCopy(iterator position, InputIterator first, InputIterator last); + void reallocateAndFillN(iterator position, const size_type& n, const value_type& val); + };// end of class vector + //***********************构造,复制,析构相关*********************** template vector::vector(const size_type n){ @@ -221,6 +234,67 @@ namespace TinySTL{ } return viter(first); } + template + template + void vector::reallocateAndCopy(iterator position, InputIterator first, InputIterator last){ + difference_type oldCapacity = endOfStorage_ - start_; + oldCapacity = oldCapacity ? oldCapacity : 1; + difference_type newCapacity = oldCapacity + std::max(oldCapacity, last - first); + + T *newStart = dataAllocator::allocate(newCapacity); + T *newEndOfStorage = newStart + newCapacity; + T *newFinish = uninitialized_copy(begin(), position, newStart); + newFinish = uninitialized_copy(first, last, newFinish); + newFinish = uninitialized_copy(position, end(), newFinish); + + destroyAndDeallocateAll(); + start_ = newStart; + finish_ = newFinish; + endOfStorage_ = newEndOfStorage; + } + template + template + void vector::insert_aux(iterator position, + InputIterator first, InputIterator last, + std::false_type){ + difference_type locationLeft = endOfStorage_ - finish_; // the size of left storage + difference_type locationNeed = last - first; + + if (locationLeft >= locationNeed){ + auto tempPtr = end() - 1; + for (; tempPtr - position >= 0; --tempPtr){//move the [position, finish_) back + *(tempPtr + locationNeed) = *tempPtr; + } + uninitialized_copy(first, last, position); + finish_ += locationNeed; + }else{ + reallocateAndCopy(position, first, last); + } + } + template + template + void vector::insert_aux(iterator position, Integer n, Integer value, std::true_type){ + vector v(n, value); + insert(position, v.begin(), v.end()); + } + template + template + void vector::insert(iterator position, InputIterator first, InputIterator last){ + insert_aux(position, first, last, typename std::is_integral::type()); + } + template + void vector::insert(iterator position, const size_type& n, const value_type& val){ + insert_aux(position, n, val, typename std::is_integral::type()); + } + template + typename vector::iterator vector::insert(iterator position, const value_type& val){ + insert(position, 1, val); + return position; + } + template + void vector::push_back(const value_type& value){ + insert(end(), value); + } } #endif \ No newline at end of file diff --git a/TinySTL/main.cpp b/TinySTL/main.cpp index aabf459..d3c30ef 100644 --- a/TinySTL/main.cpp +++ b/TinySTL/main.cpp @@ -12,7 +12,27 @@ using namespace std; int main(){ - TinySTL::vector svec(10, "hello world"); + int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + //TinySTL::vector svec(array, array + 5); + //svec.erase(svec.begin() + 1, svec.begin() + 4);//1,5 + TinySTL::vector svec; + cout << svec.capacity() << endl; + svec.push_back(1); + cout << svec.capacity() << endl; + svec.push_back(2); + cout << svec.capacity() << endl; + svec.push_back(3); + cout << svec.capacity() << endl; + svec.push_back(4); + cout << svec.capacity() << endl; + svec.push_back(5); + cout << svec.capacity() << endl; + svec.push_back(6); + cout << svec.capacity() << endl; + svec.push_back(7); + cout << svec.capacity() << endl; + //svec.insert(svec.begin() + 0, array, array + 10); + //svec.insert(svec.begin()+0, 10, 99); for (auto s : svec){ cout << s << endl; } system("pause"); return 0;