From b77522e25335c66bd82dfc72407bc09f664bdb63 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:02:51 +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/CircularBuffer.h | 225 +++----------------------- TinySTL/Detail/CircularBuffer.impl.h | 227 +++++++++++++++++++++++++++ 2 files changed, 250 insertions(+), 202 deletions(-) create mode 100644 TinySTL/Detail/CircularBuffer.impl.h diff --git a/TinySTL/CircularBuffer.h b/TinySTL/CircularBuffer.h index 468179e..a85725a 100644 --- a/TinySTL/CircularBuffer.h +++ b/TinySTL/CircularBuffer.h @@ -10,12 +10,12 @@ namespace TinySTL{ template class circular_buffer; - namespace{ + namespace Detail{ //the iterator of circular buffer template> class cb_iter:iterator{//bidirectional iterator private: - typedef circular_buffer cb; + typedef ::TinySTL::circular_buffer cb; typedef cb *cbPtr; T *ptr_; @@ -27,86 +27,39 @@ namespace TinySTL{ ptr_(ptr), index_(ptr - container->start_), container_(container){} cb_iter(const cb_iter& cit) : ptr_(cit.ptr_), index_(cit.index_), container_(cit.container_){} - cb_iter& operator = (const cb_iter& cit){ - if (this != &cit){ - ptr_ = cit.ptr_; - index_ = cit.index_; - container_ = cit.container_; - } - return *this; - } + cb_iter& operator = (const cb_iter& cit); public: operator T*(){ return ptr_; } T& operator *(){ return *ptr_; } T *operator ->(){ return &(operator*()); } - cb_iter& operator ++(){ - setIndex_(nextIndex(index_)); - setPtr_(container_->start_ + index_); - return *this; - } - cb_iter operator ++(int){ - cb_iter temp(*this); - ++(*this); - return temp; - } - cb_iter& operator --(){ - setIndex_(prevIndex(index_)); - setPtr_(container_->start_ + index_); - return *this; - } - cb_iter operator --(int){ - cb_iter temp(*this); - --(*this); - return temp; - } - bool operator == (const cb_iter& it)const{ - return (container_ == it.container_) && - (ptr_ == it.ptr_) && (index_ == it.index_); - } - bool operator != (const cb_iter& it)const{ - return !((*this) == it); - } + cb_iter& operator ++(); + cb_iter operator ++(int); + cb_iter& operator --(); + cb_iter operator --(int); + bool operator == (const cb_iter& it)const; + bool operator != (const cb_iter& it)const; private: void setIndex_(int index){ index_ = index; } void setPtr_(T *ptr){ ptr_ = ptr; } int nextIndex(int index){ return (++index) % N; } - int prevIndex(int index){ - --index; - index = (index == -1 ? index + N : index); - return index; - } + int prevIndex(int index); public: template friend cb_iter operator +(const cb_iter& cit, std::ptrdiff_t i); template friend cb_iter operator -(const cb_iter& cit, std::ptrdiff_t i); }; - template - cb_iter operator +(const cb_iter& cit, std::ptrdiff_t i){ - int real_i = i % (std::ptrdiff_t)N;//assume i >= 0 - if (real_i < 0) - real_i += 5; - cb_iter res = cit; - res.setIndex_(res.index_ + real_i); - res.setPtr_(res.ptr_ + res.index_); - return res; - } - template - cb_iter operator -(const cb_iter& cit, std::ptrdiff_t i){ - cb_iter res = cit; - return (res + (-i)); - } - }//end of anonymous namespace + }//end of Detail namespace //circular buffer template> class circular_buffer{ template - friend class cb_iter; + friend class ::TinySTL::Detail::cb_iter; public: typedef T value_type; - typedef cb_iter iterator; + typedef Detail::cb_iter iterator; typedef iterator pointer; typedef T& reference; typedef int size_type; @@ -127,21 +80,13 @@ namespace TinySTL{ circular_buffer& operator = (const circular_buffer& cb); circular_buffer& operator = (circular_buffer&& cb); circular_buffer(circular_buffer&& cb); - ~circular_buffer(){ - clear(); - dataAllocator::deallocate(start_, size_); - } + ~circular_buffer(); bool full(){ return size_ == N; } bool empty(){ return size_ == 0; } difference_type capacity(){ return finish_ - start_; } size_type size(){ return size_; } - void clear(){ - for (; !empty(); indexOfHead = nextIndex(indexOfHead), --size_){ - dataAllocator::destroy(start_ + indexOfHead); - } - indexOfHead = indexOfTail = 0; - } + void clear(); iterator first(){ return iterator(start_ + indexOfHead, this); } iterator last(){ return iterator(start_ + indexOfTail, this); } @@ -152,147 +97,23 @@ namespace TinySTL{ void push_back(const T& val); void pop_front(); - bool operator == (circular_buffer& cb){ - auto it1 = first(), it2 = cb.first(); - for (;it1 != last() && it2 != cb.last(); ++it1, ++it2){ - if (*it1 != *it2) return false; - } - return (it1 == last()) && (it2 == cb.last()) && (*(last()) == *(cb.last())); - } - bool operator != (circular_buffer& cb){ - return !(*this == cb); - } + bool operator == (circular_buffer& cb); + bool operator != (circular_buffer& cb); Alloc get_allocator(){ return dataAllocator; } private: - void allocateAndFillN(const int& n, const value_type& val){//only for ctor - start_ = dataAllocator::allocate(N); - finish_ = start_ + N; - indexOfHead = 0; - if (N <= n){ - finish_ = TinySTL::uninitialized_fill_n(start_, N, val); - indexOfTail = N - 1; - size_ = N; - }else{//N > n - finish_ = TinySTL::uninitialized_fill_n(start_, n, val); - finish_ = TinySTL::uninitialized_fill_n(finish_, N - n, value_type()); - indexOfTail = n - 1; - size_ = n; - } - } + void allocateAndFillN(const int& n, const value_type& val); template - void allocateAndCopy(InputIterator first, InputIterator last){//only for ctor - int n = last - first; - start_ = dataAllocator::allocate(N); - indexOfHead = 0; - if (N <= n){ - finish_ = TinySTL::uninitialized_copy(first, first + N, start_); - indexOfTail = N - 1; - size_ = N; - }else{//N > n - finish_ = TinySTL::uninitialized_copy(first, last, start_); - finish_ = TinySTL::uninitialized_fill_n(finish_, N - n, value_type()); - indexOfTail = n - 1; - size_ = n; - } - } + void allocateAndCopy(InputIterator first, InputIterator last); int nextIndex(int index){ return (index + 1) % N; } - void copyAllMembers(const circular_buffer& cb){ - start_ = cb.start_; - finish_ = cb.finish_; - indexOfHead = cb.indexOfHead; - indexOfTail = cb.indexOfTail; - size_ = cb.size_; - } - void zeroCircular(circular_buffer& cb){ - cb.start_ = cb.finish_ = 0; - cb.indexOfHead = cb.indexOfTail = cb.size_ = 0; - } - void clone(const circular_buffer& cb){ - start_ = dataAllocator::allocate(N); - finish_ = start_ + N; - size_ = N; - indexOfHead = cb.indexOfHead; - indexOfTail = cb.indexOfTail; - TinySTL::uninitialized_copy(cb.start_, cb.finish_, start_); - } + void copyAllMembers(const circular_buffer& cb); + void zeroCircular(circular_buffer& cb); + void clone(const circular_buffer& cb); public: template friend std::ostream& operator <<(std::ostream& os, circular_buffer& cb); };//end of circular buffer - - //**********构造,复制,析构相关***************** - template - circular_buffer::circular_buffer(const int& n, const value_type& val = value_type()){ - assert(n != 0); - allocateAndFillN(n, val); - } - template - template - circular_buffer::circular_buffer(InputIterator first, InputIterator last){ - //bug fix - //2015.01.05 - assert(first != last); - allocateAndCopy(first, last); - } - template - circular_buffer::circular_buffer(const circular_buffer& cb){ - clone(cb); - } - template - circular_buffer::circular_buffer(circular_buffer&& cb){ - copyAllMembers(cb); - zeroCircular(cb); - } - template - circular_buffer& circular_buffer::operator = (const circular_buffer& cb){ - if (this != &cb){ - clone(cb); - } - return *this; - } - template - circular_buffer& circular_buffer::operator = (circular_buffer&& cb){ - if (*this != cb){ - copyAllMembers(cb); - zeroCircular(cb); - } - return *this; - } - //************插入,删除相关*********************** - template - void circular_buffer::push_back(const T& val){ - if (full()){ - indexOfTail = nextIndex(indexOfTail); - dataAllocator::construct(start_ + indexOfTail, val); - indexOfHead = nextIndex(indexOfHead); - }else{ - indexOfTail = nextIndex(indexOfTail); - dataAllocator::construct(start_ + indexOfTail, val); - ++size_; - } - } - template - void circular_buffer::pop_front(){ - if (empty()) - throw; - dataAllocator::destroy(start_ + indexOfHead); - indexOfHead = nextIndex(indexOfHead); - --size_; - } - - template - std::ostream& operator <<(std::ostream& os, circular_buffer& cb){ - circular_buffer::size_type size = cb.size(); - if (!cb.empty()){ - os << "("; - for (auto it = cb.first(); it != cb.last() && size != 0; ++it, --size){ - os << *it << ", "; - } - os << *(cb.last()) << ")"; - } - return os; - } } +#include "Detail\CircularBuffer.impl.h" #endif \ No newline at end of file diff --git a/TinySTL/Detail/CircularBuffer.impl.h b/TinySTL/Detail/CircularBuffer.impl.h new file mode 100644 index 0000000..9ba1415 --- /dev/null +++ b/TinySTL/Detail/CircularBuffer.impl.h @@ -0,0 +1,227 @@ +#ifndef _CIRCULAR_BUFFER_IMPL_H_ +#define _CIRCULAR_BUFFER_IMPL_H_ + +namespace TinySTL{ + namespace Detail{ + template + int cb_iter::prevIndex(int index){ + --index; + index = (index == -1 ? index + N : index); + return index; + } + template + bool cb_iter::operator == (const cb_iter& it)const{ + return (container_ == it.container_) && + (ptr_ == it.ptr_) && (index_ == it.index_); + } + template + bool cb_iter::operator != (const cb_iter& it)const{ + return !((*this) == it); + } + template + cb_iter& cb_iter::operator ++(){ + setIndex_(nextIndex(index_)); + setPtr_(container_->start_ + index_); + return *this; + } + template + cb_iter cb_iter::operator ++(int){ + cb_iter temp(*this); + ++(*this); + return temp; + } + template + cb_iter& cb_iter::operator --(){ + setIndex_(prevIndex(index_)); + setPtr_(container_->start_ + index_); + return *this; + } + template + cb_iter cb_iter::operator --(int){ + cb_iter temp(*this); + --(*this); + return temp; + } + template + cb_iter& cb_iter::operator = (const cb_iter& cit){ + if (this != &cit){ + ptr_ = cit.ptr_; + index_ = cit.index_; + container_ = cit.container_; + } + return *this; + } + template + cb_iter operator +(const cb_iter& cit, std::ptrdiff_t i){ + int real_i = i % (std::ptrdiff_t)N;//assume i >= 0 + if (real_i < 0) + real_i += 5; + cb_iter res = cit; + res.setIndex_(res.index_ + real_i); + res.setPtr_(res.ptr_ + res.index_); + return res; + } + template + cb_iter operator -(const cb_iter& cit, std::ptrdiff_t i){ + cb_iter res = cit; + return (res + (-i)); + } + }//end of Detail namespace + + //**********构造,复制,析构相关***************** + template + circular_buffer::~circular_buffer(){ + clear(); + dataAllocator::deallocate(start_, size_); + } + template + circular_buffer::circular_buffer(const int& n, const value_type& val = value_type()){ + assert(n != 0); + allocateAndFillN(n, val); + } + template + template + circular_buffer::circular_buffer(InputIterator first, InputIterator last){ + //bug fix + //2015.01.05 + assert(first != last); + allocateAndCopy(first, last); + } + template + circular_buffer::circular_buffer(const circular_buffer& cb){ + clone(cb); + } + template + circular_buffer::circular_buffer(circular_buffer&& cb){ + copyAllMembers(cb); + zeroCircular(cb); + } + template + circular_buffer& circular_buffer::operator = (const circular_buffer& cb){ + if (this != &cb){ + clone(cb); + } + return *this; + } + template + circular_buffer& circular_buffer::operator = (circular_buffer&& cb){ + if (*this != cb){ + copyAllMembers(cb); + zeroCircular(cb); + } + return *this; + } + //************插入,删除相关*********************** + template + void circular_buffer::push_back(const T& val){ + if (full()){ + indexOfTail = nextIndex(indexOfTail); + dataAllocator::construct(start_ + indexOfTail, val); + indexOfHead = nextIndex(indexOfHead); + } + else{ + indexOfTail = nextIndex(indexOfTail); + dataAllocator::construct(start_ + indexOfTail, val); + ++size_; + } + } + template + void circular_buffer::pop_front(){ + if (empty()) + throw; + dataAllocator::destroy(start_ + indexOfHead); + indexOfHead = nextIndex(indexOfHead); + --size_; + } + + template + std::ostream& operator <<(std::ostream& os, circular_buffer& cb){ + circular_buffer::size_type size = cb.size(); + if (!cb.empty()){ + os << "("; + for (auto it = cb.first(); it != cb.last() && size != 0; ++it, --size){ + os << *it << ", "; + } + os << *(cb.last()) << ")"; + } + return os; + } + template + void circular_buffer::clear(){ + for (; !empty(); indexOfHead = nextIndex(indexOfHead), --size_){ + dataAllocator::destroy(start_ + indexOfHead); + } + indexOfHead = indexOfTail = 0; + } + template + bool circular_buffer::operator == (circular_buffer& cb){ + auto it1 = first(), it2 = cb.first(); + for (; it1 != last() && it2 != cb.last(); ++it1, ++it2){ + if (*it1 != *it2) return false; + } + return (it1 == last()) && (it2 == cb.last()) && (*(last()) == *(cb.last())); + } + template + bool circular_buffer::operator != (circular_buffer& cb){ + return !(*this == cb); + } + template + void circular_buffer::allocateAndFillN(const int& n, const value_type& val){//only for ctor + start_ = dataAllocator::allocate(N); + finish_ = start_ + N; + indexOfHead = 0; + if (N <= n){ + finish_ = TinySTL::uninitialized_fill_n(start_, N, val); + indexOfTail = N - 1; + size_ = N; + } + else{//N > n + finish_ = TinySTL::uninitialized_fill_n(start_, n, val); + finish_ = TinySTL::uninitialized_fill_n(finish_, N - n, value_type()); + indexOfTail = n - 1; + size_ = n; + } + } + template + template + void circular_buffer::allocateAndCopy(InputIterator first, InputIterator last){//only for ctor + int n = last - first; + start_ = dataAllocator::allocate(N); + indexOfHead = 0; + if (N <= n){ + finish_ = TinySTL::uninitialized_copy(first, first + N, start_); + indexOfTail = N - 1; + size_ = N; + } + else{//N > n + finish_ = TinySTL::uninitialized_copy(first, last, start_); + finish_ = TinySTL::uninitialized_fill_n(finish_, N - n, value_type()); + indexOfTail = n - 1; + size_ = n; + } + } + template + void circular_buffer::copyAllMembers(const circular_buffer& cb){ + start_ = cb.start_; + finish_ = cb.finish_; + indexOfHead = cb.indexOfHead; + indexOfTail = cb.indexOfTail; + size_ = cb.size_; + } + template + void circular_buffer::zeroCircular(circular_buffer& cb){ + cb.start_ = cb.finish_ = 0; + cb.indexOfHead = cb.indexOfTail = cb.size_ = 0; + } + template + void circular_buffer::clone(const circular_buffer& cb){ + start_ = dataAllocator::allocate(N); + finish_ = start_ + N; + size_ = N; + indexOfHead = cb.indexOfHead; + indexOfTail = cb.indexOfTail; + TinySTL::uninitialized_copy(cb.start_, cb.finish_, start_); + } +} + +#endif \ No newline at end of file