Deque.h 11.1 KB
Newer Older
邹晓航 已提交
1 2 3
#ifndef _DEQUE_H_
#define _DEQUE_H_

邹晓航 已提交
4
#include "Allocator.h"
5
#include "Iterator.h"
邹晓航 已提交
6
#include "ReverseIterator.h"
邹晓航 已提交
7

邹晓航 已提交
8
namespace TinySTL{
9 10 11 12 13
	template<class T, class Alloc = allocator<T>>
	class deque;
	namespace{
		//class of deque iterator
		template<class T>
邹晓航 已提交
14 15 16 17
		class dq_iter :public iterator<bidirectional_iterator_tag, T>{
		private:
			template<class T, class Alloc>
			friend class deque;
18 19 20 21 22 23
		private:
			typedef TinySTL::deque<T>* cntrPtr;
			size_t mapIndex_;
			T *cur_;
			cntrPtr container_;
		public:
邹晓航 已提交
24 25
			dq_iter() :mapIndex_(-1), cur_(0), container_(0){}
			dq_iter(size_t index, T *ptr, cntrPtr container)
26
				:mapIndex_(index), cur_(ptr), container_(container){}
邹晓航 已提交
27
			dq_iter(const dq_iter& it) 
28
				:mapIndex_(it.mapIndex_), cur_(it.cur_), container_(it.container_){}
邹晓航 已提交
29
			dq_iter& operator = (const dq_iter& it){
邹晓航 已提交
30 31 32 33
				if (this != &it){
					mapIndex_ = it.mapIndex_;
					cur_ = it.cur_;
					container_ = it.container_;
34 35 36 37 38
				}
				return *this;
			}
			reference operator *(){ return *cur_; }
			pointer operator ->(){ return &(operator*()); }
邹晓航 已提交
39
			dq_iter& operator ++(){
40 41
				if (cur_ != getBuckTail(mapIndex_))//+1后还在同一个桶里
					++cur_;
bug fix  
邹晓航 已提交
42
				else if(mapIndex_ + 1 < container_->mapSize_){//+1后还在同一个map里
43 44
					++mapIndex_;
					cur_ = getBuckHead(mapIndex_);
bug fix  
邹晓航 已提交
45
				}else{//+1后跳出了map
邹晓航 已提交
46 47 48
					mapIndex_ = container_->mapSize_;
					//cur_ = container_->map_[mapIndex_] + getBuckSize();//指向map_[mapSize_-1]的尾的下一个位置
					cur_ = container_->map_[mapIndex_];
49 50 51
				}
				return *this;
			}
邹晓航 已提交
52
			dq_iter operator ++(int){
53 54 55 56
				auto res = *this;
				++(*this);
				return res;
			}
邹晓航 已提交
57
			dq_iter& operator --(){
58 59
				if (cur_ != getBuckHead(mapIndex_))//当前不指向桶头
					--cur_;
bug fix  
邹晓航 已提交
60
				else if(mapIndex_ - 1 >= 0){//-1后还在map里面
61 62
					--mapIndex_;
					cur_ = getBuckTail(mapIndex_);
bug fix  
邹晓航 已提交
63 64 65
				}else{
					mapIndex_ = 0;
					cur_ = container_->map_[mapIndex_];//指向map_[0]的头
66 67 68
				}
				return *this;
			}
邹晓航 已提交
69
			dq_iter operator --(int){
70 71 72 73
				auto res = *this;
				--(*this);
				return res;
			}
邹晓航 已提交
74
			bool operator ==(const dq_iter& it)const{
75 76 77
				return ((mapIndex_ == it.mapIndex_) &&
					(cur_ == it.cur_) && (container_ == it.container_));
			}
邹晓航 已提交
78
			bool operator !=(const dq_iter& it)const{
79 80 81 82
				return !(*this == it);
			}
		private:
			T *getBuckTail(size_t mapIndex)const{
bug fix  
邹晓航 已提交
83
				return container_->map_[mapIndex] + (container_->getBuckSize() - 1);
84 85 86 87
			}
			T *getBuckHead(size_t mapIndex)const{
				return container_->map_[mapIndex];
			}
bug fix  
邹晓航 已提交
88 89 90
			size_t getBuckSize()const{
				return container_->getBuckSize();
			}
91 92
		public:
			template<class T>
邹晓航 已提交
93
			friend dq_iter<T> operator + (const dq_iter<T>& it, typename dq_iter<T>::difference_type n);
94
			template<class T>
邹晓航 已提交
95
			friend dq_iter<T> operator + (typename dq_iter<T>::difference_type n, const dq_iter<T>& it);
96
			template<class T>
邹晓航 已提交
97
			friend dq_iter<T> operator - (const dq_iter<T>& it, typename dq_iter<T>::difference_type n);
98
			template<class T>
邹晓航 已提交
99
			friend dq_iter<T> operator - (typename dq_iter<T>::difference_type n, const dq_iter<T>& it);
100
			template<class T>
邹晓航 已提交
101
			friend typename dq_iter<T>::difference_type operator - (const dq_iter<T>& it1, const dq_iter<T>& it2);
102 103
		};
		template<class T>
邹晓航 已提交
104 105
		dq_iter<T> operator + (const dq_iter<T>& it, typename dq_iter<T>::difference_type n){//assume n >= 0
			dq_iter<T> res(it);
106 107 108 109 110 111
			auto m = res.getBuckTail(res.mapIndex_) - res.cur_;
			if (n <= m){//前进n步仍在同一个桶中
				res.cur_ += n;
			}
			else{
				n = n - m;
bug fix  
邹晓航 已提交
112 113 114 115
				res.mapIndex_ += (n / it.getBuckSize() + 1);
				auto p = res.getBuckHead(res.mapIndex_);
				auto x = n % it.getBuckSize() - 1;
				res.cur_ = p + x;
116 117 118 119
			}
			return res;
		}
		template<class T>
邹晓航 已提交
120
		dq_iter<T> operator + (typename dq_iter<T>::difference_type n, const dq_iter<T>& it){
121 122 123
			return (it + n);
		}
		template<class T>
邹晓航 已提交
124 125
		dq_iter<T> operator - (const dq_iter<T>& it, typename dq_iter<T>::difference_type n){//assume n >= 0
			dq_iter<T> res(it);
126 127 128 129 130
			auto m = res.cur_ - res.getBuckHead(res.mapIndex_);
			if (n <= m)//后退n步还在同一个桶中
				res.cur_ -= n;
			else{
				n = n - m;
bug fix  
邹晓航 已提交
131 132
				res.mapIndex_ -= (n / res.getBuckSize() + 1);
				res.cur_ = res.getBuckTail(res.mapIndex_) - (n % res.getBuckSize() - 1);
133 134 135 136
			}
			return res;
		}
		template<class T>
邹晓航 已提交
137
		dq_iter<T> operator - (typename dq_iter<T>::difference_type n, const dq_iter<T>& it){
138 139 140
			return (it - n);
		}
		template<class T>
邹晓航 已提交
141
		typename dq_iter<T>::difference_type operator - (const dq_iter<T>& it1, const dq_iter<T>& it2){
邹晓航 已提交
142 143
			if (it1.container_ == it2.container_ && it1.container_ == 0)
				return 0;
bug fix  
邹晓航 已提交
144 145
			return typename dq_iter<T>::difference_type(it1.getBuckSize()) * (it1.mapIndex_ - it2.mapIndex_ - 1)
				+ (it1.cur_ - it1.getBuckHead(it1.mapIndex_)) + (it2.getBuckTail(it2.mapIndex_) - it2.cur_) + 1;
146 147
		}
	}
邹晓航 已提交
148

邹晓航 已提交
149
	//class of deque
150
	template<class T, class Alloc>
邹晓航 已提交
151
	class deque{
152 153
	private:
		template<class T>
邹晓航 已提交
154
		friend class dq_iter;
邹晓航 已提交
155 156
	public:
		typedef T value_type;
邹晓航 已提交
157
		typedef dq_iter<T> iterator;
邹晓航 已提交
158 159 160 161 162
		typedef const iterator const_iterator;
		typedef T& reference;
		typedef const reference const_reference;
		typedef size_t size_type;
		typedef ptrdiff_t difference_type;
163
		typedef Alloc allocator_type;
邹晓航 已提交
164 165
	private:
		typedef Alloc dataAllocator;
166 167 168 169 170
		enum class EBucksSize{BUCKSIZE = 64};
	private:
		iterator beg_, end_;
		size_t mapSize_;
		T **map_;
邹晓航 已提交
171
	public:
172
		deque();
邹晓航 已提交
173 174 175
		explicit deque(size_type n, const value_type& val = value_type());
		template <class InputIterator>
		deque(InputIterator first, InputIterator last);
邹晓航 已提交
176 177
		deque(const deque& x);

178
		~deque(){
邹晓航 已提交
179 180 181 182
			for (int i = 0; i != mapSize_; ++i)
				if (!map_[i])
					dataAllocator::deallocate(map_[i], getBuckSize());
			delete[] map_;
183
		}
邹晓航 已提交
184 185 186 187

		deque& operator= (const deque& x);
		deque& operator= (deque&& x);

邹晓航 已提交
188 189 190
		iterator begin(){ return beg_; }
		const_iterator begin() const{ return beg_; }
		iterator end(){ return end_; }
bug fix  
邹晓航 已提交
191
		const_iterator end() const{ return end_; }
邹晓航 已提交
192 193
		const_iterator cbegin() const{ return beg_; }
		const_iterator cend() const{ return end_; }
邹晓航 已提交
194

邹晓航 已提交
195 196
		size_type size() const{ return end() - begin(); }
		bool empty() const{ return begin() == end(); }
邹晓航 已提交
197

bug fix  
邹晓航 已提交
198 199 200 201 202 203
		reference operator[] (size_type n){ return *(begin() + n); }
		const_reference operator[] (size_type n) const{ return *(cbegin() + n); }
		reference front(){ return *begin(); }
		const_reference front() const{ return *cbegin(); }
		reference back(){ return *(end() - 1); }
		const_reference back() const{ return *(cend() - 1); }
邹晓航 已提交
204 205 206 207 208 209

		void push_back(const value_type& val);
		void push_front(const value_type& val);
		void pop_back();
		void pop_front();
		void swap(deque& x);
邹晓航 已提交
210 211 212
		void clear(){
			for (int i = 0; i != mapSize_; ++i)
				if (!map_[i])
邹晓航 已提交
213 214 215 216
					dataAllocator::destroy(map_[i], map_[i] + getBuckSize());
			mapSize_ = 0;
			beg_.mapIndex_ = end_.mapIndex_ = mapSize_ / 2;
			beg_.cur_ = end_.cur_ = map_[mapSize_ / 2];
217
		}
邹晓航 已提交
218
	private:
swap  
邹晓航 已提交
219 220 221
		T *getANewBuck(){
			return dataAllocator::allocate(getBuckSize());
		}
222
		T** getANewMap(const size_t size){
邹晓航 已提交
223 224
			T **map = new T*[size];
			for (int i = 0; i != size; ++i)
swap  
邹晓航 已提交
225
				map[i] = getANewBuck();
邹晓航 已提交
226
			return map;
bug fix  
邹晓航 已提交
227 228
		}
		size_t getNewMapSize(const size_t size){
邹晓航 已提交
229
			return (size == 0 ? 2 : size * 2);
230 231
		}
		size_t getBuckSize()const{
邹晓航 已提交
232
			return (size_t)EBucksSize::BUCKSIZE;
233
		}
bug fix  
邹晓航 已提交
234 235 236 237 238 239 240 241
		void init(){
			mapSize_ = 2;
			map_ = getANewMap(mapSize_);
			beg_.container_ = end_.container_ = this;
			beg_.mapIndex_ = end_.mapIndex_ = mapSize_ - 1;
			beg_.cur_ = end_.cur_ = map_[mapSize_ - 1];
		}
		bool back_full()const{ 
邹晓航 已提交
242
			return map_[mapSize_ - 1] && (map_[mapSize_]) == end().cur_;
bug fix  
邹晓航 已提交
243 244 245 246
		}
		bool front_full()const{
			return map_[0] && map_[0] == begin().cur_;
		}
邹晓航 已提交
247 248 249 250 251 252 253 254 255 256
		void deque_aux(size_t n, const value_type& val, std::true_type){
			int i = 0;
			for (; i != n / 2; ++i)
				(*this).push_front(val);
			for (; i != n; ++i)
				(*this).push_back(val);
		}
		template<class Iterator>
		void deque_aux(Iterator first, Iterator last, std::false_type){
			difference_type mid = (last - first) / 2;
邹晓航 已提交
257
			for (auto it = first + mid; it != first - 1; --it)
邹晓航 已提交
258 259 260 261
				(*this).push_front(*it);
			for (auto it = first + mid + 1; it != last; ++it)
				(*this).push_back(*it);
		}
邹晓航 已提交
262
		void reallocateAndCopy();
邹晓航 已提交
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
	public:
		template <class T, class Alloc>
		friend bool operator== (const deque<T, Alloc>& lhs, const deque<T, Alloc>& rhs);
		template <class T, class Alloc>
		friend bool operator!= (const deque<T, Alloc>& lhs, const deque<T, Alloc>& rhs);
		template <class T, class Alloc>
		friend bool operator<  (const deque<T, Alloc>& lhs, const deque<T, Alloc>& rhs);
		template <class T, class Alloc>
		friend bool operator<= (const deque<T, Alloc>& lhs, const deque<T, Alloc>& rhs);
		template <class T, class Alloc>
		friend bool operator>  (const deque<T, Alloc>& lhs, const deque<T, Alloc>& rhs);
		template <class T, class Alloc>
		friend bool operator>= (const deque<T, Alloc>& lhs, const deque<T, Alloc>& rhs);
		template <class T, class Alloc>
		friend void swap(deque<T, Alloc>& x, deque<T, Alloc>& y);
	};//end of deque
279 280 281 282

	template<class T, class Alloc>
	deque<T, Alloc>::deque()
		:mapSize_(0), map_(0){}
邹晓航 已提交
283 284 285 286 287 288 289 290 291 292 293
	template<class T, class Alloc>
	deque<T, Alloc>::deque(size_type n, const value_type& val = value_type()){
		deque();
		deque_aux(n, val, typename std::is_integral<size_type>::type());
	}
	template<class T, class Alloc>
	template <class InputIterator>
	deque<T, Alloc>::deque(InputIterator first, InputIterator last){
		deque();
		deque_aux(first, last, typename std::is_integral<InputIterator>::type());
	}
邹晓航 已提交
294
	template<class T, class Alloc>
bug fix  
邹晓航 已提交
295
	deque<T, Alloc>::deque(const deque& x){
邹晓航 已提交
296 297 298 299 300 301 302 303 304 305 306
		mapSize_ = x.mapSize_;
		map_ = getANewMap(mapSize_);
		for (int i = 0; i + x.beg_.mapIndex_ != x.mapSize_; ++i)
			for (int j = 0; j != getBuckSize(); ++j)
				map_[x.beg_.mapIndex_ + i][j] = x.map_[x.beg_.mapIndex_ + i][j];
		beg_.mapIndex_ = x.beg_.mapIndex_;
		end_.mapIndex_ = x.end_.mapIndex_;
		beg_.cur_ = map_[beg_.mapIndex_] + (x.beg_.cur_ - x.map_[x.beg_.mapIndex_]);
		end_.cur_ = map_[end_.mapIndex_] + (x.end_.cur_ - x.map_[x.end_.mapIndex_]);
		beg_.container_ = end_.container_ = this;
	}
邹晓航 已提交
307
	template<class T, class Alloc>
邹晓航 已提交
308 309 310
	void deque<T, Alloc>::reallocateAndCopy(){
		auto newMapSize = getNewMapSize(mapSize_);
		T** newMap = getANewMap(newMapSize);
311
		size_t startIndex = newMapSize / 4;
邹晓航 已提交
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
		for (int i = 0; i + beg_.mapIndex_ != mapSize_; ++i)
			for (int j = 0; j != getBuckSize(); ++j)
				newMap[startIndex + i][j] = map_[beg_.mapIndex_ + i][j];

		size_t n = beg_.cur_ - map_[beg_.mapIndex_];
		auto size = this->size();
		auto b = beg_, e = end_;
		clear();
		mapSize_ = newMapSize;
		map_ = newMap;
		beg_ = iterator(startIndex, newMap[startIndex] + n, this);
		end_ = beg_ + size;
		
	}
	template<class T, class Alloc>
bug fix  
邹晓航 已提交
327 328 329 330 331
	void deque<T, Alloc>::push_back(const value_type& val){
		if (empty()){
			init();
		}
		else if (back_full()){
邹晓航 已提交
332
			reallocateAndCopy();
bug fix  
邹晓航 已提交
333 334 335 336 337 338 339 340 341 342
		}
		*end_ = val;
		++end_;
	}
	template<class T, class Alloc>
	void deque<T, Alloc>::push_front(const value_type& val){
		if (empty()){
			init();
		}
		else if (front_full()){
邹晓航 已提交
343
			reallocateAndCopy();
bug fix  
邹晓航 已提交
344 345 346
		}
		--beg_;
		*beg_ = val;
邹晓航 已提交
347
	}
邹晓航 已提交
348 349 350
	template<class T, class Alloc>
	void deque<T, Alloc>::pop_front(){
		dataAllocator::destroy(beg_.cur_);
邹晓航 已提交
351
		++beg_;
邹晓航 已提交
352 353 354 355 356 357
	}
	template<class T, class Alloc>
	void deque<T, Alloc>::pop_back(){
		--end_;
		dataAllocator::destroy(end_.cur_);
	}
swap  
邹晓航 已提交
358 359 360 361 362 363 364
	template<class T, class Alloc>
	void deque<T, Alloc>::swap(deque& x){
		TinySTL::swap(beg_, x.beg_);
		TinySTL::swap(end_, x.end_);
		TinySTL::swap(mapSize_, x.mapSize_);
		TinySTL::swap(map_, x.map_);
	}
邹晓航 已提交
365 366
}
#endif