STL源码剖析(五)序列式容器之vector

序列式容器
研究数据的特定排列方式,以利于搜索或排序或其它特殊目的,称为数据结构。
STL容器将运用最广的一些数据结构实现出来。
常用的数据结构不外乎array(数组), list(链表), tree(树), stack(堆栈), queue(队列), hash table(散列表), set(集合), map(映射),根据数据在容器中排列的特性,数据结构又分为序列式(sequence)和关联式(associative)。

序列式容器,其中元素可序,但未必有序。
C++提供序列式容器array,STL提供vector, list, deque, stack, queue, priority-queue等序列式容器。
其中stack和queue只是将deque改头换面而已,技术上归类为一种配接器。

vector
vector维护的是一个连续线性空间,普通指针也可作为vector的迭代器使用。
vector提供的迭代器是Random Access Iterators。
为了降低空间配置时的速度成本,vector实际配置大小比需求量更大,以备将来可能的扩充,这便是容量capacity。

uninitialized_fill_n()根据第一参数的类型特性,type traits,决定使用算法fill_n()或反复调用construct()来完成任务。
动态增加大小,并不是在原空间之后续接新空间,而是以原大小的两倍另外配置一块较大空间,然后将原内容拷贝过来,然后在原内容之后构造新元素,并释放原空间。

namespace std _GLIBCXX_VISIBILITY(default)
{
  template<typename _Tp, typename _Alloc>
    struct _Vector_base
    {
      //声明内存分配器_Alloc下rebind<_Tp>::other别名为_Tp_alloc_type
      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
	  rebind<_Tp>::other _Tp_alloc_type
	  //pointer声明为_Alloc<_Tp>::pointer即_Tp*
      typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
       	pointer;
     
      struct _Vector_impl //vector内存分配器
      : public _Tp_alloc_type //继承自_Alloc<_Tp>
      { //增加配置空间的指针_M_start、_M_finish、_M_end_of_storage
	    pointer _M_start;  //表已配置空间的头
	    pointer _M_finish; //表已配置空间的尾
	    pointer _M_end_of_storage; //表可用空间的尾
	    
	    //以下省略部分构造函数
		void _M_swap_data(_Vector_impl& __x) _GLIBCXX_NOEXCEPT //交换函数
		{ //使用算法std::swap完成配置空间指针值的交换
		  std::swap(_M_start, __x._M_start);
		  std::swap(_M_finish, __x._M_finish);
		  std::swap(_M_end_of_storage, __x._M_end_of_storage);
		}
      }; //vector内存结构及分配
    public:
      typedef _Alloc allocator_type; //_Alloc重命名为allocator_type

      _Tp_alloc_type& //取成员_M_impl,static_cast将该成员由派生类转换为基类并返回
      _M_get_Tp_allocator() _GLIBCXX_NOEXCEPT
      { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); }
     
      allocator_type //将_M_get_Tp_allocator返回的类型成员构造临时allocator_type对象返回
      get_allocator() const _GLIBCXX_NOEXCEPT
      { return allocator_type(_M_get_Tp_allocator()); }
      //以下省略部分构造函数和析构函数
    
    public:
      _Vector_impl _M_impl;
      
      pointer //分配一段原始的、未构造的内存,大小为n
      _M_allocate(size_t __n)
      {
		typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
		return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer();
      }
     
      void //释放地址p开始大小为n的内存
      _M_deallocate(pointer __p, size_t __n)
      {
		typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type> _Tr;
		if (__p)
		  _Tr::deallocate(_M_impl, __p, __n);
      }

    private:
      void //创建内存空间,并初始化类内成员
      _M_create_storage(size_t __n)
      {
		this->_M_impl._M_start = this->_M_allocate(__n);
		this->_M_impl._M_finish = this->_M_impl._M_start;
		this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
      }
    }; //模板类_Vector_base定义完成

  //模板类vector,缺省使用allocator作为空间配置器
  template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
    class vector : protected _Vector_base<_Tp, _Alloc>
    {

      static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value,
	  "std::vector must have a non-const, non-volatile value_type");

      typedef _Vector_base<_Tp, _Alloc>			_Base; //继承类型
      typedef typename _Base::_Tp_alloc_type		_Tp_alloc_type;
      typedef __gnu_cxx::__alloc_traits<_Tp_alloc_type>	_Alloc_traits;

    public: //vector内嵌类型定义
      typedef _Tp					value_type;
      typedef typename _Base::pointer			pointer; //指针
      typedef typename _Alloc_traits::const_pointer	const_pointer;
      typedef typename _Alloc_traits::reference		reference; //左值引用
      typedef typename _Alloc_traits::const_reference	const_reference;
      typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator; //迭代器
      typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
      const_iterator;
      typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
      typedef std::reverse_iterator<iterator>		reverse_iterator; //反向迭代器
      typedef size_t					size_type;
      typedef ptrdiff_t					difference_type; //两元素之间的距离
      typedef _Alloc					allocator_type; //内存分配器

    protected: //基类成员访问控制
      using _Base::_M_allocate;
      using _Base::_M_deallocate;
      using _Base::_M_impl;
      using _Base::_M_get_Tp_allocator;
   
    public:
      //以下构造函数
      vector() //默认构造函数
      noexcept(is_nothrow_default_constructible<_Alloc>::value)
      : _Base() { }
      explicit //构造函数,不可隐式类型转换
      vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
      : _Base(__a) { }
     
      explicit //分配__n个内存空间
      vector(size_type __n, const allocator_type& __a = allocator_type())
      : _Base(__n, __a)
      { _M_default_initialize(__n); }
     
      vector(size_type __n, const value_type& __value,
	     const allocator_type& __a = allocator_type()) //分配__n个内存空间,并初始化为__value
      : _Base(__n, __a)
      { _M_fill_initialize(__n, __value); }
     
      vector(const vector& __x) //拷贝构造函数
      : _Base(__x.size(),
		_Alloc_traits::_S_select_on_copy(__x._M_get_Tp_allocator()))
	  {
		this->_M_impl._M_finish =
		  std::__uninitialized_copy_a(__x.begin(), __x.end(),
					      this->_M_impl._M_start,
					      _M_get_Tp_allocator());
      }
     
      vector(vector&& __x) noexcept //移动构造函数,通知标准库不抛出异常
      : _Base(std::move(__x)) { }
     
      vector(const vector& __x, const allocator_type& __a)
      : _Base(__x.size(), __a)
      {
		this->_M_impl._M_finish =
		  std::__uninitialized_copy_a(__x.begin(), __x.end(),
					      this->_M_impl._M_start,
					      _M_get_Tp_allocator());
      }

      vector(vector&& __rv, const allocator_type& __m)
      noexcept(_Alloc_traits::_S_always_equal())
      : _Base(std::move(__rv), __m)
      {
		if (__rv.get_allocator() != __m)
		  {
		    this->_M_impl._M_finish =
		      std::__uninitialized_move_a(__rv.begin(), __rv.end(),
						  this->_M_impl._M_start,
						  _M_get_Tp_allocator());
		    __rv.clear();
		  }
      }

      vector(initializer_list<value_type> __l,
	     const allocator_type& __a = allocator_type()) //初始值列表
      : _Base(__a)
      {
		_M_range_initialize(__l.begin(), __l.end(),
				    random_access_iterator_tag());
      }

      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
		vector(_InputIterator __first, _InputIterator __last,
		       const allocator_type& __a = allocator_type()) //指定迭代器范围初始化
		: _Base(__a)
		{ _M_initialize_dispatch(__first, __last, __false_type()); }

      ~vector() _GLIBCXX_NOEXCEPT //析构函数
      {
      	std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
		      _M_get_Tp_allocator());
		      _GLIBCXX_ASAN_ANNOTATE_BEFORE_DEALLOC;
      }
	  //赋值运算符重载,可接受左值引用、右值引用及初始值列表赋值
      vector& 
      operator=(const vector& __x);

      vector&
      operator=(vector&& __x) noexcept(_Alloc_traits::_S_nothrow_move())
      {
		constexpr bool __move_storage =
		  _Alloc_traits::_S_propagate_on_move_assign()
		  || _Alloc_traits::_S_always_equal();
		_M_move_assign(std::move(__x), __bool_constant<__move_storage>());
		return *this;
      }

      vector&
      operator=(initializer_list<value_type> __l)
      {
		this->_M_assign_aux(__l.begin(), __l.end(),
				    random_access_iterator_tag());
		return *this;
      }
      //assign,接受大小及初始值、迭代器范围、初始值列表
      void
      assign(size_type __n, const value_type& __val)
      { _M_fill_assign(__n, __val); }

      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
		void
		assign(_InputIterator __first, _InputIterator __last)
		{ _M_assign_dispatch(__first, __last, __false_type()); }

      void
      assign(initializer_list<value_type> __l)
      {
		this->_M_assign_aux(__l.begin(), __l.end(),
				    random_access_iterator_tag());
      }
      using _Base::get_allocator;
      
      //begin、end、rbegin、rend,省略const迭代器返回
      iterator
      begin() _GLIBCXX_NOEXCEPT
      { return iterator(this->_M_impl._M_start); }
      iterator
      end() _GLIBCXX_NOEXCEPT
      { return iterator(this->_M_impl._M_finish); }
      reverse_iterator
      rbegin() _GLIBCXX_NOEXCEPT
      { return reverse_iterator(end()); }
      reverse_iterator
      rend() _GLIBCXX_NOEXCEPT
      { return reverse_iterator(begin()); }
      //cbegin、cend、crbegin、crend
      const_iterator
      cbegin() const noexcept
      { return const_iterator(this->_M_impl._M_start); }
      const_iterator
      cend() const noexcept
      { return const_iterator(this->_M_impl._M_finish); }
      const_reverse_iterator
      crbegin() const noexcept
      { return const_reverse_iterator(end()); }
      const_reverse_iterator
      crend() const noexcept
      { return const_reverse_iterator(begin()); }
      
      size_type
      size() const _GLIBCXX_NOEXCEPT //已保存元素数目
      { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }

      size_type //可最大保存元素数目
      max_size() const _GLIBCXX_NOEXCEPT //获取内存分配器的属性
      { return _Alloc_traits::max_size(_M_get_Tp_allocator()); }
      
      //增大或缩小容器
      void
      resize(size_type __new_size)
      {
		if (__new_size > size())
		  _M_default_append(__new_size - size());
		else if (__new_size < size())
		  _M_erase_at_end(this->_M_impl._M_start + __new_size);
      }
      void
      resize(size_type __new_size, const value_type& __x)
      {
		if (__new_size > size())
		  _M_fill_insert(end(), __new_size - size(), __x);
		else if (__new_size < size())
		  _M_erase_at_end(this->_M_impl._M_start + __new_size);
      }

      void
      shrink_to_fit() //将capacity()减少为与size()相同大小
      { _M_shrink_to_fit(); }

      size_type //容器容量
      capacity() const _GLIBCXX_NOEXCEPT //不重新分配内存空间下,可以保存多少元素
      { return size_type(this->_M_impl._M_end_of_storage
			 - this->_M_impl._M_start); }

      bool //容器是否为空
      empty() const _GLIBCXX_NOEXCEPT
      { return begin() == end(); }

      void
      reserve(size_type __n); //分配至少容纳n个元素的内存空间。
    
      //下标运算符重载,省略返回const引用
      reference
      operator[](size_type __n) _GLIBCXX_NOEXCEPT
      {
		__glibcxx_requires_subscript(__n);
		return *(this->_M_impl._M_start + __n);
      }

    protected:
      void //检查__n是否在容器范围内
      _M_range_check(size_type __n) const //at中安全检查,下标运算符不检查
      {
		if (__n >= this->size())
		  __throw_out_of_range_fmt(__N("vector::_M_range_check: __n "
					       "(which is %zu) >= this->size() "
					       "(which is %zu)"),
					   __n, this->size());
      }

    public:
      //at、front、back、data,省略返回const引用或指针
      reference
      at(size_type __n)
      {
		_M_range_check(__n); //安全检查
		return (*this)[__n]; //调用下标运算符
      }
      reference
      front() _GLIBCXX_NOEXCEPT
      {
		__glibcxx_requires_nonempty();
		return *begin();
      }
      reference
      back() _GLIBCXX_NOEXCEPT
      {
		__glibcxx_requires_nonempty();
		return *(end() - 1);
      }
      _Tp*
      data() _GLIBCXX_NOEXCEPT
      { return _M_data_ptr(this->_M_impl._M_start); }
      
      //push_back,接受左值引用、右值引用
      void
      push_back(const value_type& __x)
      {
		if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
		  {
		    _GLIBCXX_ASAN_ANNOTATE_GROW(1);
		    _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
					     __x);
		    ++this->_M_impl._M_finish;
		    _GLIBCXX_ASAN_ANNOTATE_GREW(1);
		  }
		else
		  _M_realloc_insert(end(), __x);
      }
      void
      push_back(value_type&& __x)
      { emplace_back(std::move(__x)); }
      
      //emplace_back
      template<typename... _Args>
		void
		emplace_back(_Args&&... __args);

      void
      pop_back() _GLIBCXX_NOEXCEPT
      {
		__glibcxx_requires_nonempty();
		--this->_M_impl._M_finish;
		_Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
		_GLIBCXX_ASAN_ANNOTATE_SHRINK(1);
      }

      template<typename... _Args>
		iterator
		emplace(const_iterator __position, _Args&&... __args)
		{ return _M_emplace_aux(__position, std::forward<_Args>(__args)...); }

      //insert插入操作
      iterator
      insert(const_iterator __position, const value_type& __x);

      iterator
      insert(const_iterator __position, value_type&& __x)
      { return _M_insert_rval(__position, std::move(__x)); }

      iterator
      insert(const_iterator __position, initializer_list<value_type> __l)
      {
		auto __offset = __position - cbegin();
		_M_range_insert(begin() + __offset, __l.begin(), __l.end(),
				std::random_access_iterator_tag());
		return begin() + __offset;
      }

      iterator
      insert(const_iterator __position, size_type __n, const value_type& __x)
      {
		difference_type __offset = __position - cbegin();
		_M_fill_insert(begin() + __offset, __n, __x);
		return begin() + __offset;
      }

      template<typename _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
		iterator
		insert(const_iterator __position, _InputIterator __first,
		       _InputIterator __last)
		{
		  difference_type __offset = __position - cbegin();
		  _M_insert_dispatch(begin() + __offset,
				     __first, __last, __false_type());
		  return begin() + __offset;
		}
      //erase
      iterator
      erase(const_iterator __position)
      { return _M_erase(begin() + (__position - cbegin())); }

      iterator
      erase(const_iterator __first, const_iterator __last)
      {
		const auto __beg = begin();
		const auto __cbeg = cbegin();
		return _M_erase(__beg + (__first - __cbeg), __beg + (__last - __cbeg));
      }
      //swap
      void
      swap(vector& __x) _GLIBCXX_NOEXCEPT
      {
		__glibcxx_assert(_Alloc_traits::propagate_on_container_swap::value
				 || _M_get_Tp_allocator() == __x._M_get_Tp_allocator());
		this->_M_impl._M_swap_data(__x._M_impl);
		_Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
					  __x._M_get_Tp_allocator());
      }
      //clear
      void
      clear() _GLIBCXX_NOEXCEPT
      { _M_erase_at_end(this->_M_impl._M_start); }
      //以下省略部分内容
    };
  //容器比较
  template<typename _Tp, typename _Alloc>
    inline bool
    operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
    { return (__x.size() == __y.size()
	      && std::equal(__x.begin(), __x.end(), __y.begin())); }

  template<typename _Tp, typename _Alloc>
    inline bool
    operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
    { return std::lexicographical_compare(__x.begin(), __x.end(),
					  __y.begin(), __y.end()); }

  /// Based on operator==
  template<typename _Tp, typename _Alloc>
    inline bool
    operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
    { return !(__x == __y); } //调用相等运算符比较

  /// Based on operator<
  template<typename _Tp, typename _Alloc>
    inline bool
    operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
    { return __y < __x; } //调用<运算符比较

  /// Based on operator<
  template<typename _Tp, typename _Alloc>
    inline bool
    operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
    { return !(__y < __x); } //调用<运算符比较

  /// Based on operator<
  template<typename _Tp, typename _Alloc>
    inline bool
    operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
    { return !(__x < __y); } //调用<运算符比较

  /// See std::vector::swap().
  template<typename _Tp, typename _Alloc>
    inline void
    swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
    _GLIBCXX_NOEXCEPT_IF(noexcept(__x.swap(__y)))
    { __x.swap(__y); } //容器交换

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值