From 54ff18eb4355a4ccefdb91607910d0a0e927c9f5 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, 12 Jan 2015 13:37:21 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TinySTL/Detail/Vector.impl.h | 287 +++++++++++++++++++++++++++++++++++ TinySTL/Vector.h | 276 ++------------------------------- 2 files changed, 299 insertions(+), 264 deletions(-) create mode 100644 TinySTL/Detail/Vector.impl.h diff --git a/TinySTL/Detail/Vector.impl.h b/TinySTL/Detail/Vector.impl.h new file mode 100644 index 0000000..dc1f820 --- /dev/null +++ b/TinySTL/Detail/Vector.impl.h @@ -0,0 +1,287 @@ +#ifndef _VECTOR_IMPL_H_ +#define _VECTOR_IMPL_H_ + +namespace TinySTL{ + //***********************构造,复制,析构相关*********************** + template + vector::~vector(){ + destroyAndDeallocateAll(); + } + template + vector::vector(const size_type n){ + allocateAndFillN(n, value_type()); + } + template + vector::vector(const size_type n, const value_type& value){ + allocateAndFillN(n, value); + } + template + template + vector::vector(InputIterator first, InputIterator last){ + //处理指针和数字间的区别的函数 + vector_aux(first, last, typename std::is_integral::type()); + } + template + vector::vector(const vector& v){ + allocateAndCopy(v.start_, v.finish_); + } + template + vector::vector(vector&& v){ + start_ = v.start_; + finish_ = v.finish_; + endOfStorage_ = v.endOfStorage_; + v.start_ = v.finish_ = v.endOfStorage_ = 0; + } + template + vector& vector::operator = (const vector& v){ + if (this != &v){ + allocateAndCopy(v.start_, v.finish_); + } + return *this; + } + template + vector& vector::operator = (vector&& v){ + if (this != &v){ + destroyAndDeallocateAll(); + start_ = v.start_; + finish_ = v.finish_; + endOfStorage_ = v.endOfStorage_; + v.start_ = v.finish_ = v.endOfStorage_ = 0; + } + return *this; + } + //*************和容器的容量相关****************************** + template + void vector::resize(size_type n, value_type val = value_type()){ + if (n < size()){ + dataAllocator::destroy(start_ + n, finish_); + finish_ = start_ + n; + } + else if (n > size() && n <= capacity()){ + auto lengthOfInsert = n - size(); + finish_ = uninitialized_fill_n(finish_, lengthOfInsert, val); + } + else if (n > capacity()){ + auto lengthOfInsert = n - size(); + T *newStart = dataAllocator::allocate(getNewCapacity(lengthOfInsert)); + T *newFinish = TinySTL::uninitialized_copy(begin(), end(), newStart); + newFinish = TinySTL::uninitialized_fill_n(newFinish, lengthOfInsert, val); + + destroyAndDeallocateAll(); + start_ = newStart; + finish_ = newFinish; + endOfStorage_ = start_ + n; + } + } + template + void vector::reserve(size_type n){ + if (n <= capacity()) + return; + T *newStart = dataAllocator::allocate(n); + T *newFinish = TinySTL::uninitialized_copy(begin(), end(), newStart); + destroyAndDeallocateAll(); + + start_ = newStart; + finish_ = newFinish; + endOfStorage_ = start_ + n; + } + //***************修改容器的相关操作************************** + template + typename vector::iterator vector::erase(iterator position){ + return erase(position, position + 1); + } + template + typename vector::iterator vector::erase(iterator first, iterator last){ + //尾部残留对象数 + difference_type lenOfTail = end() - last; + //删去的对象数目 + difference_type lenOfRemoved = last - first; + finish_ = finish_ - lenOfRemoved; + for (; lenOfTail != 0; --lenOfTail){ + auto temp = (last - lenOfRemoved); + *temp = *(last++); + } + return (first); + } + template + template + void vector::reallocateAndCopy(iterator position, InputIterator first, InputIterator last){ + difference_type newCapacity = getNewCapacity(last - first); + + T *newStart = dataAllocator::allocate(newCapacity); + T *newEndOfStorage = newStart + newCapacity; + T *newFinish = TinySTL::uninitialized_copy(begin(), position, newStart); + newFinish = TinySTL::uninitialized_copy(first, last, newFinish); + newFinish = TinySTL::uninitialized_copy(position, end(), newFinish); + + destroyAndDeallocateAll(); + start_ = newStart; + finish_ = newFinish; + endOfStorage_ = newEndOfStorage; + } + template + void vector::reallocateAndFillN(iterator position, const size_type& n, const value_type& val){ + difference_type newCapacity = getNewCapacity(n); + + T *newStart = dataAllocator::allocate(newCapacity); + T *newEndOfStorage = newStart + newCapacity; + T *newFinish = TinySTL::uninitialized_copy(begin(), position, newStart); + newFinish = TinySTL::uninitialized_fill_n(newFinish, n, val); + newFinish = TinySTL::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){ + iterator tempPtr = end() - 1; + for (; tempPtr - position >= 0; --tempPtr){//move the [position, finish_) back + *(tempPtr + locationNeed) = *tempPtr; + } + TinySTL::uninitialized_copy(first, last, position); + finish_ += locationNeed; + } + else{ + reallocateAndCopy(position, first, last); + } + } + template + template + void vector::insert_aux(iterator position, Integer n, const value_type& value, std::true_type){ + assert(n != 0); + difference_type locationLeft = endOfStorage_ - finish_; // the size of left storage + difference_type locationNeed = n; + + if (locationLeft >= locationNeed){ + auto tempPtr = end() - 1; + for (; tempPtr - position >= 0; --tempPtr){//move the [position, finish_) back + *(tempPtr + locationNeed) = *tempPtr; + } + TinySTL::uninitialized_fill_n(position, n, value); + finish_ += locationNeed; + } + else{ + reallocateAndFillN(position, n, value); + } + } + 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){ + const auto index = position - begin(); + insert(position, 1, val); + return begin() + index; + } + template + void vector::push_back(const value_type& value){ + insert(end(), value); + } + //***********逻辑比较操作相关******************* + template + bool vector::operator == (const vector& v)const{ + if (size() != v.size()){ + return false; + } + else{ + auto ptr1 = start_; + auto ptr2 = v.start_; + for (; ptr1 != finish_ && ptr2 != v.finish_; ++ptr1, ++ptr2){ + if (*ptr1 != *ptr2) + return false; + } + return true; + } + } + template + bool vector::operator != (const vector& v)const{ + return !(*this == v); + } + template + bool operator == (const vector& v1, const vector& v2){ + //return v1 == v2; + return v1.operator==(v2); + } + template + bool operator != (const vector& v1, const vector& v2){ + return !(v1 == v2); + } + template + void vector::shrink_to_fit(){ + dataAllocator::deallocate(finish_, endOfStorage_ - finish_); + endOfStorage_ = finish_; + } + template + void vector::clear(){ + dataAllocator::destroy(start_, finish_); + finish_ = start_; + } + template + void vector::swap(vector& v){ + if (this != &v){ + TinySTL::swap(start_, v.start_); + TinySTL::swap(finish_, v.finish_); + TinySTL::swap(endOfStorage_, v.endOfStorage_); + } + } + template + void vector::pop_back(){ + --finish_; + dataAllocator::destroy(finish_); + } + template + void vector::destroyAndDeallocateAll(){ + if (capacity() != 0){ + dataAllocator::destroy(start_, finish_); + dataAllocator::deallocate(start_, capacity()); + } + } + template + void vector::allocateAndFillN(const size_type n, const value_type& value){ + start_ = dataAllocator::allocate(n); + TinySTL::uninitialized_fill_n(start_, n, value); + finish_ = endOfStorage_ = start_ + n; + } + template + template + void vector::allocateAndCopy(InputIterator first, InputIterator last){ + start_ = dataAllocator::allocate(last - first); + finish_ = TinySTL::uninitialized_copy(first, last, start_); + endOfStorage_ = finish_; + } + template + template + void vector::vector_aux(InputIterator first, InputIterator last, std::false_type){ + allocateAndCopy(first, last); + } + template + template + void vector::vector_aux(Integer n, const value_type& value, std::true_type){ + allocateAndFillN(n, value); + } + template + typename vector::size_type vector::getNewCapacity(size_type len)const{ + size_type oldCapacity = endOfStorage_ - start_; + auto res = TinySTL::max(oldCapacity, len); + size_type newCapacity = (oldCapacity != 0 ? (oldCapacity + res) : len); + return newCapacity; + } +} + +#endif \ No newline at end of file diff --git a/TinySTL/Vector.h b/TinySTL/Vector.h index 0bdf510..5a1d641 100644 --- a/TinySTL/Vector.h +++ b/TinySTL/Vector.h @@ -44,9 +44,7 @@ namespace TinySTL{ vector(vector&& v); vector& operator = (const vector& v); vector& operator = (vector&& v); - ~vector(){ - destroyAndDeallocateAll(); - } + ~vector(); //比较操作相关 bool operator == (const vector& v)const; @@ -70,10 +68,7 @@ namespace TinySTL{ bool empty()const{ return start_ == finish_; } void resize(size_type n, value_type val = value_type()); void reserve(size_type n); - void shrink_to_fit(){ - dataAllocator::deallocate(finish_, endOfStorage_ - finish_); - endOfStorage_ = finish_; - } + void shrink_to_fit(); //访问元素相关 value_type& operator[](const difference_type i){ return *(begin() + i); } @@ -83,22 +78,10 @@ namespace TinySTL{ //修改容器相关的操作 //清空容器,销毁容器中的所有对象并使容器的size为0,但不回收容器已有的空间 - void clear(){ - dataAllocator::destroy(start_, finish_); - finish_ = start_; - } - void swap(vector& v){ - if (this != &v){ - TinySTL::swap(start_, v.start_); - TinySTL::swap(finish_, v.finish_); - TinySTL::swap(endOfStorage_, v.endOfStorage_); - } - } + void clear(); + void swap(vector& v); void push_back(const value_type& value); - void pop_back(){ - --finish_; - dataAllocator::destroy(finish_); - } + void pop_back(); iterator insert(iterator position, const value_type& val); void insert(iterator position, const size_type& n, const value_type& val); template @@ -109,32 +92,15 @@ namespace TinySTL{ //容器的空间配置器相关 Alloc get_allocator(){ return dataAllocator; } private: - void destroyAndDeallocateAll(){ - if (capacity() != 0){ - dataAllocator::destroy(start_, finish_); - dataAllocator::deallocate(start_, capacity()); - } - } - void allocateAndFillN(const size_type n, const value_type& value){ - start_ = dataAllocator::allocate(n); - TinySTL::uninitialized_fill_n(start_, n, value); - finish_ = endOfStorage_ = start_ + n; - } + void destroyAndDeallocateAll(); + void allocateAndFillN(const size_type n, const value_type& value); template - void allocateAndCopy(InputIterator first, InputIterator last){ - start_ = dataAllocator::allocate(last - first); - finish_ = TinySTL::uninitialized_copy(first, last, start_); - endOfStorage_ = finish_; - } + void allocateAndCopy(InputIterator first, InputIterator last); template - void vector_aux(InputIterator first, InputIterator last, std::false_type){ - allocateAndCopy(first, last); - } + void vector_aux(InputIterator first, InputIterator last, std::false_type); template - void vector_aux(Integer n, const value_type& value, std::true_type){ - allocateAndFillN(n, value); - } + void vector_aux(Integer n, const value_type& value, std::true_type); template void insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type); template @@ -142,232 +108,14 @@ namespace TinySTL{ template void reallocateAndCopy(iterator position, InputIterator first, InputIterator last); void reallocateAndFillN(iterator position, const size_type& n, const value_type& val); - size_type getNewCapacity(size_type len)const{ - size_type oldCapacity = endOfStorage_ - start_; - auto res = TinySTL::max(oldCapacity, len); - size_type newCapacity = (oldCapacity != 0 ? (oldCapacity + res) : len); - return newCapacity; - } + size_type getNewCapacity(size_type len)const; public: template friend bool operator == (const vector& v1, const vector& v2); template friend bool operator != (const vector& v1, const vector& v2); };// end of class vector - - //***********************构造,复制,析构相关*********************** - template - vector::vector(const size_type n){ - allocateAndFillN(n, value_type()); - } - template - vector::vector(const size_type n, const value_type& value){ - allocateAndFillN(n, value); - } - template - template - vector::vector(InputIterator first, InputIterator last){ - //处理指针和数字间的区别的函数 - vector_aux(first, last, typename std::is_integral::type()); - } - template - vector::vector(const vector& v){ - allocateAndCopy(v.start_, v.finish_); - } - template - vector::vector(vector&& v){ - start_ = v.start_; - finish_ = v.finish_; - endOfStorage_ = v.endOfStorage_; - v.start_ = v.finish_ = v.endOfStorage_ = 0; - } - template - vector& vector::operator = (const vector& v){ - if (this != &v){ - allocateAndCopy(v.start_, v.finish_); - } - return *this; - } - template - vector& vector::operator = (vector&& v){ - if (this != &v){ - destroyAndDeallocateAll(); - start_ = v.start_; - finish_ = v.finish_; - endOfStorage_ = v.endOfStorage_; - v.start_ = v.finish_ = v.endOfStorage_ = 0; - } - return *this; - } - //*************和容器的容量相关****************************** - template - void vector::resize(size_type n, value_type val = value_type()){ - if (n < size()){ - dataAllocator::destroy(start_ + n, finish_); - finish_ = start_ + n; - }else if (n > size() && n <= capacity()){ - auto lengthOfInsert = n - size(); - finish_ = uninitialized_fill_n(finish_, lengthOfInsert, val); - }else if (n > capacity()){ - auto lengthOfInsert = n - size(); - T *newStart = dataAllocator::allocate(getNewCapacity(lengthOfInsert)); - T *newFinish = TinySTL::uninitialized_copy(begin(), end(), newStart); - newFinish = TinySTL::uninitialized_fill_n(newFinish, lengthOfInsert, val); - - destroyAndDeallocateAll(); - start_ = newStart; - finish_ = newFinish; - endOfStorage_ = start_ + n; - } - } - template - void vector::reserve(size_type n){ - if (n <= capacity()) - return; - T *newStart = dataAllocator::allocate(n); - T *newFinish = TinySTL::uninitialized_copy(begin(), end(), newStart); - destroyAndDeallocateAll(); - - start_ = newStart; - finish_ = newFinish; - endOfStorage_ = start_ + n; - } - //***************修改容器的相关操作************************** - template - typename vector::iterator vector::erase(iterator position){ - return erase(position, position + 1); - } - template - typename vector::iterator vector::erase(iterator first, iterator last){ - //尾部残留对象数 - difference_type lenOfTail = end() - last; - //删去的对象数目 - difference_type lenOfRemoved = last - first; - finish_ = finish_ - lenOfRemoved; - for (; lenOfTail != 0; --lenOfTail){ - auto temp = (last - lenOfRemoved); - *temp = *(last++); - } - return (first); - } - template - template - void vector::reallocateAndCopy(iterator position, InputIterator first, InputIterator last){ - difference_type newCapacity = getNewCapacity(last - first); - - T *newStart = dataAllocator::allocate(newCapacity); - T *newEndOfStorage = newStart + newCapacity; - T *newFinish = TinySTL::uninitialized_copy(begin(), position, newStart); - newFinish = TinySTL::uninitialized_copy(first, last, newFinish); - newFinish = TinySTL::uninitialized_copy(position, end(), newFinish); - - destroyAndDeallocateAll(); - start_ = newStart; - finish_ = newFinish; - endOfStorage_ = newEndOfStorage; - } - template - void vector::reallocateAndFillN(iterator position, const size_type& n, const value_type& val){ - difference_type newCapacity = getNewCapacity(n); - - T *newStart = dataAllocator::allocate(newCapacity); - T *newEndOfStorage = newStart + newCapacity; - T *newFinish = TinySTL::uninitialized_copy(begin(), position, newStart); - newFinish = TinySTL::uninitialized_fill_n(newFinish, n, val); - newFinish = TinySTL::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){ - iterator tempPtr = end() - 1; - for (; tempPtr - position >= 0; --tempPtr){//move the [position, finish_) back - *(tempPtr + locationNeed) = *tempPtr; - } - TinySTL::uninitialized_copy(first, last, position); - finish_ += locationNeed; - }else{ - reallocateAndCopy(position, first, last); - } - } - template - template - void vector::insert_aux(iterator position, Integer n, const value_type& value, std::true_type){ - assert(n != 0); - difference_type locationLeft = endOfStorage_ - finish_; // the size of left storage - difference_type locationNeed = n; - - if (locationLeft >= locationNeed){ - auto tempPtr = end() - 1; - for (; tempPtr - position >= 0; --tempPtr){//move the [position, finish_) back - *(tempPtr + locationNeed) = *tempPtr; - } - TinySTL::uninitialized_fill_n(position, n, value); - finish_ += locationNeed; - } - else{ - reallocateAndFillN(position, n, value); - } - } - 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){ - const auto index = position - begin(); - insert(position, 1, val); - return begin() + index; - } - template - void vector::push_back(const value_type& value){ - insert(end(), value); - } - //***********逻辑比较操作相关******************* - template - bool vector::operator == (const vector& v)const{ - if (size() != v.size()){ - return false; - } - else{ - auto ptr1 = start_; - auto ptr2 = v.start_; - for (; ptr1 != finish_ && ptr2 != v.finish_; ++ptr1, ++ptr2){ - if (*ptr1 != *ptr2) - return false; - } - return true; - } - } - template - bool vector::operator != (const vector& v)const{ - return !(*this == v); - } - template - bool operator == (const vector& v1, const vector& v2){ - //return v1 == v2; - return v1.operator==(v2); - } - template - bool operator != (const vector& v1, const vector& v2){ - return !(v1 == v2); - } } +#include "Detail\Vector.impl.h" #endif \ No newline at end of file