STL源码剖析(七)序列式容器之deque迭代器设计

deque概述
vector是单向开口的连续线性空间,deque是双向开口的连续线性空间。
双向开口,意思是可以在首尾两端分别做元素的插入和删除操作。
deque允许常数时间内对首尾两端进行元素的插入或删除,且deque没有容量capacity的概念,因为它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来,因此不需要提供所谓的空间保留功能。
deque提供Ramdom Access Iterator,但迭代器不是普通指针,更复杂,当然会影响各个运算层面,因此,除非必要,应尽可能选择使用vector而非deque。
对deque排序,先将deque复制到vector排序完成后,再复制回deque。

deque的中控器
deque是连续空间,逻辑上看是如此,deque是一段一段定量连续空间,串接在整个deque的首端或尾端,deque的最大任务便是在这些分段的定量连续空间上,维护其整体连续的假象,并提供随机存取的接口。
避开了重新配置、复制、释放的轮回,代价是复杂的迭代器架构。
deque采用map(不是STL的map容器)作为主控,map是一小段连续空间,每个元素指向另一段较大连续线性空间,称为缓冲区,缓冲区才是deque的储存空间主体。
deque是分段连续空间,维持整体连续假象的任务,落在了迭代器operator++和operator—运算符上。

namespace std _GLIBCXX_VISIBILITY(default)
{
#ifndef _GLIBCXX_DEQUE_BUF_SIZE
#define _GLIBCXX_DEQUE_BUF_SIZE 512 //宏定义缓冲区大小为512bytes
#endif

  _GLIBCXX_CONSTEXPR inline size_t
  __deque_buf_size(size_t __size) //元素大小__size小于512时返回512/__size,不小于512时返回1
  { return (__size < _GLIBCXX_DEQUE_BUF_SIZE
	    ? size_t(_GLIBCXX_DEQUE_BUF_SIZE / __size) : size_t(1)); }

  //deque迭代器定义,未继承std::iterator
  template<typename _Tp, typename _Ref, typename _Ptr>
    struct _Deque_iterator
    {
    private:
      template<typename _Up> //_Up的指针类型,__ptr_to<_Up>等于*_Up
		using __ptr_to = typename pointer_traits<_Ptr>::template rebind<_Up>;
      template<typename _CvTp> //类型_CvTp的迭代器__iter<_CvTp>
		using __iter = _Deque_iterator<_Tp, _CvTp&, __ptr_to<_CvTp>>;
    public: //类型别名
      typedef __iter<_Tp>		iterator; //迭代器
      typedef __iter<const _Tp>		const_iterator; //常量迭代器
      typedef __ptr_to<_Tp>		_Elt_pointer; //元素的指针类型,*_Tp
      typedef __ptr_to<_Elt_pointer>	_Map_pointer; //指向元素的指针的指针,**_Tp

      static size_t _S_buffer_size() _GLIBCXX_NOEXCEPT //当前缓冲区可存储元素长度,调用__deque_buf_size
      { return __deque_buf_size(sizeof(_Tp)); } //__deque_buf_size为全局函数
      //未继承std::iterator,需自定义迭代器内嵌类型
      typedef std::random_access_iterator_tag	iterator_category; //1,迭代器类型-随机访问迭代器
      typedef _Tp				value_type; //2,迭代器所指元素类型
      typedef _Ptr				pointer; //3,指针类型
      typedef _Ref				reference; //4,引用类型
      typedef size_t				size_type;
      typedef ptrdiff_t				difference_type; //5,两迭代器之间距离
      typedef _Deque_iterator			_Self; //自身
      //保持与容器的连结
      _Elt_pointer _M_cur; //此迭代器所指缓冲区中的当前元素
      _Elt_pointer _M_first; //此迭代器所指缓冲区中的头
      _Elt_pointer _M_last; //此迭代器所指缓冲区的尾,包含备用空间
      _Map_pointer _M_node; //指向中控中心,此迭代器在中控中心的位置

      _Deque_iterator(_Elt_pointer __x, _Map_pointer __y) _GLIBCXX_NOEXCEPT //构造函数
      : _M_cur(__x), _M_first(*__y),
	   _M_last(*__y + _S_buffer_size()), _M_node(__y) { }

      _Deque_iterator() _GLIBCXX_NOEXCEPT //默认构造函数
      : _M_cur(), _M_first(), _M_last(), _M_node() { }

      _Deque_iterator(const iterator& __x) _GLIBCXX_NOEXCEPT //拷贝构造函数
      : _M_cur(__x._M_cur), _M_first(__x._M_first),
	   _M_last(__x._M_last), _M_node(__x._M_node) { }

      iterator //返回当前迭代器
      _M_const_cast() const _GLIBCXX_NOEXCEPT
      { return iterator(_M_cur, _M_node); }
      
      //以下重载各种指针运算
      reference //解引用迭代器
      operator*() const _GLIBCXX_NOEXCEPT
      { return *_M_cur; }

      pointer //成员访问
      operator->() const _GLIBCXX_NOEXCEPT
      { return _M_cur; }

      _Self& //递增运算符++,前置版本
      operator++() _GLIBCXX_NOEXCEPT
      {
		++_M_cur; //当前元素前进+1
		if (_M_cur == _M_last) //当前元素为尾元素时,到达缓冲区边缘
		  {
		    _M_set_node(_M_node + 1); //调用_M_set_node跳到下一个缓冲区
		    _M_cur = _M_first; //赋值当前元素为首元素
		  }
		return *this; //返回迭代器本身
      }

      _Self //递增运算符++,后置版本
      operator++(int) _GLIBCXX_NOEXCEPT
      {
		_Self __tmp = *this; //先备份
		++*this; //后递增,调用前置版本完成递增
		return __tmp; //返回备份
      }

      _Self& //递减运算符,前置版本
      operator--() _GLIBCXX_NOEXCEPT
      {
		if (_M_cur == _M_first) //当前元素为缓冲区首元素时
		  {
		    _M_set_node(_M_node - 1); //切换到前一个缓冲区
		    _M_cur = _M_last; //赋值当前元素为尾元素
		  }
		--_M_cur; //当前元素-1
		return *this; //返回
      }

      _Self //递减运算符,后置版本
      operator--(int) _GLIBCXX_NOEXCEPT
      {
		_Self __tmp = *this; //先备份
		--*this; //调用递减前置版本
		return __tmp; //返回备份
      }

      _Self& //前进+=n复合运算符,n可为负
      operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
      {
		const difference_type __offset = __n + (_M_cur - _M_first);
		if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) //__offset小于存储长度时
		  _M_cur += __n; //当前元素前进+n,_M_cur为指针类型可直接+n
		else //若超过缓冲区长度
		  {
		    const difference_type __node_offset =
		      __offset > 0 ? __offset / difference_type(_S_buffer_size())
				   : -difference_type((-__offset - 1) //兼容__offset小于0情况
						      / _S_buffer_size()) - 1; //判断需要跳转多少个缓冲区
		    _M_set_node(_M_node + __node_offset); //跳转缓冲区
		    _M_cur = _M_first + (__offset - __node_offset
					 * difference_type(_S_buffer_size())); //赋值当前元素位置
		  }
		return *this; //返回自身
      }

      _Self //前进+n
      operator+(difference_type __n) const _GLIBCXX_NOEXCEPT
      {
		_Self __tmp = *this; //先备份
		return __tmp += __n; //调用+=n复合运算符并返回,自身不发生改变
      }

      _Self& //后退-=n复合运算符
      operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
      { return *this += -__n; } //调用+=-n复合运算符

      _Self //后退-n
      operator-(difference_type __n) const _GLIBCXX_NOEXCEPT
      {
		_Self __tmp = *this; //先备份
		return __tmp -= __n; //调用-=n复合运算符并返回,自身不发生改变
      }

      reference //下标运算符
      operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
      { return *(*this + __n); } //调用+n运算符并返回元素引用

      void //当遇缓冲区边缘时,需要跳一个缓冲区
      _M_set_node(_Map_pointer __new_node) _GLIBCXX_NOEXCEPT
      {
		_M_node = __new_node; //修改此迭代器在中控中心的位置
		_M_first = *__new_node; //迭代器首元素位置
		_M_last = _M_first + difference_type(_S_buffer_size()); //迭代器尾元素位置
      }
    }; //_Deque_iterator

  //重载迭代器各种比较运算符
  template<typename _Tp, typename _Ref, typename _Ptr>
    inline bool //相等==运算符
    operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
    { return __x._M_cur == __y._M_cur; }

  template<typename _Tp, typename _RefL, typename _PtrL,
	   typename _RefR, typename _PtrR>
    inline bool
    operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
    { return __x._M_cur == __y._M_cur; }

  template<typename _Tp, typename _Ref, typename _Ptr>
    inline bool //不等!=运算符
    operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
    { return !(__x == __y); }

  template<typename _Tp, typename _RefL, typename _PtrL,
	   typename _RefR, typename _PtrR>
    inline bool
    operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
    { return !(__x == __y); }

  template<typename _Tp, typename _Ref, typename _Ptr>
    inline bool //小于<运算符
    operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
    { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
					  : (__x._M_node < __y._M_node); }

  template<typename _Tp, typename _RefL, typename _PtrL,
	   typename _RefR, typename _PtrR>
    inline bool
    operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
    { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
					  : (__x._M_node < __y._M_node); }

  template<typename _Tp, typename _Ref, typename _Ptr>
    inline bool //大于>运算符
    operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
    { return __y < __x; } //调用小于<运算符完成比较

  template<typename _Tp, typename _RefL, typename _PtrL,
	   typename _RefR, typename _PtrR>
    inline bool
    operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
    { return __y < __x; }

  template<typename _Tp, typename _Ref, typename _Ptr>
    inline bool //小于或等于<=运算符
    operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
    { return !(__y < __x); } //调用小于<运算符完成比较

  template<typename _Tp, typename _RefL, typename _PtrL,
	   typename _RefR, typename _PtrR>
    inline bool
    operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
    { return !(__y < __x); }

  template<typename _Tp, typename _Ref, typename _Ptr>
    inline bool //大于或等于>=运算符
    operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
    { return !(__x < __y); } //调用小于<运算符完成比较

  template<typename _Tp, typename _RefL, typename _PtrL,
	   typename _RefR, typename _PtrR>
    inline bool
    operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
    { return !(__x < __y); }

  template<typename _Tp, typename _Ref, typename _Ptr> //-运算符,得到两迭代器之间距离
    inline typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type
    operator-(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) _GLIBCXX_NOEXCEPT
    {
      return typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type
		(_Deque_iterator<_Tp, _Ref, _Ptr>::_S_buffer_size()) //跨缓冲区时,乘以跨缓冲区的个数
		* (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first)
		+ (__y._M_last - __y._M_cur);
    }

  template<typename _Tp, typename _RefL, typename _PtrL,
	   typename _RefR, typename _PtrR>
    inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
    operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) _GLIBCXX_NOEXCEPT
    {
      return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
		(_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size())
		* (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first)
		+ (__y._M_last - __y._M_cur);
    }

  template<typename _Tp, typename _Ref, typename _Ptr> //+运算符
    inline _Deque_iterator<_Tp, _Ref, _Ptr>
    operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
    _GLIBCXX_NOEXCEPT
    { return __x + __n; } //迭代器+n

  template<typename _Tp>
    void
    fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>&,
	 const _Deque_iterator<_Tp, _Tp&, _Tp*>&, const _Tp&);

  template<typename _Tp>
    inline _Deque_iterator<_Tp, _Tp&, _Tp*>
    copy(_Deque_iterator<_Tp, _Tp&, _Tp*> __first,
	 _Deque_iterator<_Tp, _Tp&, _Tp*> __last,
	 _Deque_iterator<_Tp, _Tp&, _Tp*> __result) //调用std::copy完成拷贝操作
    { return std::copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first),
		       _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last),
		       __result); }

  template<typename _Tp>
    inline _Deque_iterator<_Tp, _Tp&, _Tp*>
    copy_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first,
		  _Deque_iterator<_Tp, _Tp&, _Tp*> __last,
		  _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
    { return std::copy_backward(_Deque_iterator<_Tp,
				const _Tp&, const _Tp*>(__first),
				_Deque_iterator<_Tp,
				const _Tp&, const _Tp*>(__last),
				__result); }

  template<typename _Tp>
    inline _Deque_iterator<_Tp, _Tp&, _Tp*>
    move(_Deque_iterator<_Tp, _Tp&, _Tp*> __first,
	 _Deque_iterator<_Tp, _Tp&, _Tp*> __last,
	 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
    { return std::move(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first),
		       _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last),
		       __result); }

  template<typename _Tp>
    inline _Deque_iterator<_Tp, _Tp&, _Tp*>
    move_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first,
		  _Deque_iterator<_Tp, _Tp&, _Tp*> __last,
		  _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
    { return std::move_backward(_Deque_iterator<_Tp,
				const _Tp&, const _Tp*>(__first),
				_Deque_iterator<_Tp,
				const _Tp&, const _Tp*>(__last),
				__result); }

} // namespace std
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值