STL 的 rope 分析(四)

#-rope #-STL

####类模板 _Rope_const_iterator####

_Rope_const_iterator 作为 rope 的常量迭代器。它继承自 _Rope_iterator_base 。

template<class _CharT, class _Alloc>
class _Rope_const_iterator : public _Rope_iterator_base<_CharT,_Alloc> {

定义了三个成员类型,分别为 _RopeRep, reference, pointer

typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
typedef _CharT reference;
typedef const _CharT* pointer;

并定义了一系列的构造函数,因为 _Rope_const_iterator 中没有定义额外的成员变量,构造函数中都是用来初始化基类。

    _Rope_const_iterator() {};
    _Rope_const_iterator(const _Rope_const_iterator& __x) :
				_Rope_iterator_base<_CharT,_Alloc>(__x) { }
    _Rope_const_iterator(const rope<_CharT,_Alloc>& __r, size_t __pos) :
	_Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos) {}
    _Rope_const_iterator(const _RopeRep* __root, size_t __pos):
		   _Rope_iterator_base<_CharT,_Alloc>(
		     const_cast<_RopeRep*>(__root), __pos) {}
	_Rope_const_iterator<_CharT, _Alloc>::_Rope_const_iterator(
	  const _Rope_iterator<_CharT,_Alloc>& __x)
	: _Rope_iterator_base<_CharT,_Alloc>(__x) { }

函数 operator= 用指定的 _Rope_const_iterator __x 来初始化当前迭代器,如果 __x 的 _M_buf_ptr 不为 0,即缓冲区有效,则直接使用软拷贝用 __x 中的所有参数更新当前迭代器的参数,否则用 __x 中的对用值更新 _M_current_pos, _M_root 并将 _M_buf_ptr 置为 0。当缓冲区有效时,认为迭代器中的所有参数都是正确的,这也是前面直接进行软拷贝的原因,而当缓冲区无效是,迭代器的参数中只认为 _M_root 和 _M_current_pos 是正确的,而所有的参数都可以由这两个参数计算获得。

    _Rope_const_iterator& operator= (const _Rope_const_iterator& __x) {
	if (0 != __x._M_buf_ptr) {
	    *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x;
	} else {
	    _M_current_pos = __x._M_current_pos;
	    _M_root = __x._M_root;
	    _M_buf_ptr = 0;
	}
	return(*this);
    }

函数 operator*() 返回当前迭代器索引的元素,如果缓冲区无效,则调用 _S_setcache 函数重新设置迭代器的参数。然后返回 _M_buf_ptr 所指向的值。

    reference operator*() {
	if (0 == _M_buf_ptr) _S_setcache(*this);
	return *_M_buf_ptr;
    }

函数 operator++ 用来将当前迭代器往后移动一个位置。

    _Rope_const_iterator& operator++() {
	__GC_CONST _CharT* __next;
	if (0 != _M_buf_ptr && (__next = _M_buf_ptr + 1) < _M_buf_end) {
	    _M_buf_ptr = __next;
	    ++_M_current_pos;
	} else {
	    _M_incr(1);
	}
	return *this;
    }

函数 operator+= 用来将当前迭代器往后移动 __n 个位置。

    _Rope_const_iterator& operator+=(ptrdiff_t __n) {
	if (__n >= 0) {
	    _M_incr(__n);
	} else {
	    _M_decr(-__n);
	}
	return *this;
    }

函数 operator– 用来将当前迭代器往前移动一个位置。

    _Rope_const_iterator& operator--() {
	_M_decr(1);
	return *this;
    }

函数 operator-= 用来将当前迭代器往前移动 __n 个位置。

    _Rope_const_iterator& operator-=(ptrdiff_t __n) {
	if (__n >= 0) {
	    _M_decr(__n);
	} else {
	    _M_incr(-__n);
	}
	return *this;
    }

函数 operator[] 用来获取当前迭代器往后 __n 个位置的元素值。

    reference operator[](size_t __n) {
	return rope<_CharT,_Alloc>::_S_fetch(_M_root, _M_current_pos + __n);
    }

####_Rope_iterator_rope####

_Rope_iterator 是 rope 中的迭代器,它继承自 _Rope_iterator_base。

template<class _CharT, class _Alloc>
class _Rope_iterator : public _Rope_iterator_base<_CharT,_Alloc> {

_Rope_iterator 中定义了一个成员变量

    rope<_CharT,_Alloc>* _M_root_rope;

同时定义了两个成员类型 reference 和 pointer

    typedef _Rope_char_ref_proxy<_CharT,_Alloc>  reference;
    typedef _Rope_char_ref_proxy<_CharT,_Alloc>* pointer;

构造函数中对基类和 _M_root_rope 进行初始化,同时如果 rope 不为空,则调用 _S_setcache 设置迭代器的参数。

    _Rope_iterator(rope<_CharT,_Alloc>* __r, size_t __pos)
      : _Rope_iterator_base<_CharT,_Alloc>(__r->_M_tree_ptr, __pos),
	_M_root_rope(__r) 
       {  if (!(__r -> empty()))_S_setcache(*this); }

第一个为空构造函数,第二个拷贝构造函数中先用 __x 调用基类的拷贝对基类进行初始化,然后初始化 _M_root_rope。第三个构造函数也是先对基类进行初始化,然后初始化 _M_root_rope 的值。

	_Rope_iterator() { _M_root = 0; }
	_Rope_iterator(const _Rope_iterator& __x) :
	_Rope_iterator_base<_CharT,_Alloc>(__x) {
	_M_root_rope = __x._M_root_rope;
	}
	_Rope_iterator<_CharT,_Alloc>::_Rope_iterator(
	  rope<_CharT,_Alloc>& __r, size_t __pos)
	: _Rope_iterator_base<_CharT,_Alloc>(__r._M_tree_ptr, __pos),
	  _M_root_rope(&__r) {}

函数 _M_check 用来检测 _M_root_rope 和 _M_root 指示的是否是同一个 rope ,如果不是,则更新 _M_root 的值,并将迭代器中的 _M_buf_ptr 置为 0 。

void _Rope_iterator<_CharT,_Alloc>::_M_check() {
    if (_M_root_rope->_M_tree_ptr != _M_root) {
	_M_root = _M_root_rope->_M_tree_ptr;
	_M_buf_ptr = 0;
    }
}

函数 operator=() 用指定迭代器 __x 中的内容来更新当前迭代器,如果 __x 中 _M_buf_ptr 不为 0 ,则认为迭代器中一切参数都正确,则直接使用软拷贝将 __x 中参数复制到当前迭代器。否则更新 _M_current_pos, _M_root 和 _M_root_rope 的值,并将 _M_buf_ptr 置为 0 。

    _Rope_iterator& operator= (const _Rope_iterator& __x) {
	_RopeRep* __old = _M_root;
	if (0 != __x._M_buf_ptr) {
	    _M_root_rope = __x._M_root_rope;
	    *(static_cast<_Rope_iterator_base<_CharT,_Alloc>*>(this)) = __x;
	} else {
	    _M_current_pos = __x._M_current_pos;
	    _M_root = __x._M_root;
	    _M_root_rope = __x._M_root_rope;
	    _M_buf_ptr = 0;
	}
	return(*this);
    }

operator*() 返回当前迭代器的索引(这里没有直接返回值,而是返回了有给定 rope 和该值在 rope 中的位置构造而成的 _Rope_char_ref_proxy 的实例。

    reference operator*() {
	_M_check();
	if (0 == _M_buf_ptr) {
	    return _Rope_char_ref_proxy<_CharT,_Alloc>(
	       _M_root_rope, _M_current_pos);
	} else {
	    return _Rope_char_ref_proxy<_CharT,_Alloc>(
	       _M_root_rope, _M_current_pos, *_M_buf_ptr);
	}
    }

函数 operator++ 将当前迭代器往后移动一个位置。

    _Rope_iterator& operator++() {
	_M_incr(1);
	return *this;
    }

函数 operator+= 将当前迭代器往后移动 __n 个位置。

    _Rope_iterator& operator+=(ptrdiff_t __n) {
	if (__n >= 0) {
	    _M_incr(__n);
	} else {
	    _M_decr(-__n);
	}
	return *this;
    }

函数 operator– 将当前迭代器往前移动一个位置。

    _Rope_iterator& operator--() {
	_M_decr(1);
	return *this;
    }

函数 operator-= 将当前迭代器往往前移动 __n 个位置。

    _Rope_iterator& operator-=(ptrdiff_t __n) {
	if (__n >= 0) {
	    _M_decr(__n);
	} else {
	    _M_incr(-__n);
	}
	return *this;
    }

函数 operator[] 返回当前迭代器之后 __n 个位置的元素索引。

    reference operator[](ptrdiff_t __n) {
	return _Rope_char_ref_proxy<_CharT,_Alloc>(
	  _M_root_rope, _M_current_pos + __n);
    }

####类模板 _Rope_alloc_base####

_Rope_alloc_base 用来为 rope 中的元素分配和回收空间。

template <class _CharT, class _Allocator, bool _IsStatic>
class _Rope_alloc_base {

其中定义了两个成员类型。 typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep; typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type allocator_type;

_Rope_alloc_base 中一共定义了两个成员变量,其中 _M_data_allocator 用来分配和回收内存,而 _M_tree_ptr 表示整个 rope 的根节点。由它可以索引整个 rope 。

    allocator_type _M_data_allocator;
    _RopeRep* _M_tree_ptr;

和前面 _Rope_alloc_rep_base 一样,在 _Rope_alloc_base 中也定义了一个 _ROPE_DEFINE_ALLOC 的宏。

# define __ROPE_DEFINE_ALLOC(_Tp, __name) \
	typedef typename \
	  _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \
	_Tp* __name##_allocate(size_t __n) const \
	  { return __name##Allocator(_M_data_allocator).allocate(__n); } \
	void __name##_deallocate(_Tp *__p, size_t __n) const \
		{ __name##Allocator(_M_data_allocator).deallocate(__p, __n); }

和前面 _Rope_alloc_rep_base 一样,将 _ROPE_DEFINE_ALLOCS(_Allocator) 展开之后,当前类中会定义 _DataAllocator, _CAllocator, _FAllocator, _SAllocator 五种成员类型,同时定义了十个成员函数分别为 _Data_allocate, _Data_deallocate, _L_allocate, _L_deallocte, _C_allocate, _C_deallocte, _F_allocate, _F_deallocate, _S_allocate, _S_deallocte。分别为五种类型的变量分配空间。然后解除了 __ROPE_DEFINE_ALLOC 的宏定义。

  __ROPE_DEFINE_ALLOCS(_Allocator)
# undef __ROPE_DEFINE_ALLOC

####_Rope_alloc_base的偏特化####

当 _Rope_alloc_base 中当第三个模板实参为 true 时使用如下的偏特化定义,对比默认的定义,偏特化定义中少了成员变量 _M_data_allocator。同时应用宏定义 __ROPE_DEFINE_ALLOC 和宏定义 __ROPE_DEFINE_ALLOCS。将 __ROPE_DEFINE_ALLOCS(_Allocator) 展开之后,会得到十个成员类型分别为 _DataAlloc, _DataAllocator, _CAlloc, _CAllocator, _LAlloc, _LAllocator, _FAlloc, _FAllocator, _SAlloc, _SAllocator。同时定义了十个成员函数,分别为 _Data_allocate, _L_allocate, _C_allocate, _F_allocate, _S_allocate, _Data_deallocate, _L_deallocte, _C_deallocte, _F_deallocate, _S_deallocte。分别为五种类型的变量分配空间。其中前五个函数为静态成员函数,然后解除了 __ROPE_DEFINE_ALLOC 的宏定义。

template <class _CharT, class _Allocator>
class _Rope_alloc_base<_CharT,_Allocator,true> {
public:
  typedef _Rope_RopeRep<_CharT,_Allocator> _RopeRep;
  typedef typename _Alloc_traits<_CharT,_Allocator>::allocator_type
	  allocator_type;
  allocator_type get_allocator() const { return allocator_type(); }
  _Rope_alloc_base(_RopeRep *__t, const allocator_type&)
		: _M_tree_ptr(__t) {}
  _Rope_alloc_base(const allocator_type&) {}
  
protected:
  // The only data member of a rope:
    _RopeRep *_M_tree_ptr;

# define __ROPE_DEFINE_ALLOC(_Tp, __name) \
	typedef typename \
	  _Alloc_traits<_Tp,_Allocator>::_Alloc_type __name##Alloc; \
	typedef typename \
	  _Alloc_traits<_Tp,_Allocator>::allocator_type __name##Allocator; \
	static _Tp* __name##_allocate(size_t __n) \
	  { return __name##Alloc::allocate(__n); } \
	static void __name##_deallocate(_Tp *__p, size_t __n) \
	  { __name##Alloc::deallocate(__p, __n); }
  __ROPE_DEFINE_ALLOCS(_Allocator)
# undef __ROPE_DEFINE_ALLOC
};

####类模板 _Rope_base####

_Rope_base 继承自 _Rope_alloc_base<_CharT,_Alloc,_Alloc, _Alloc_traits<_CharT, _Alloc>::_S_instanceless>,_Alloc_traits 中会根据 _Alloc 的不同实例是否有区别而分别为 false 和 true (有区别是为 false, 否则为 true )。并实例基类的不同定义。

template <class _CharT, class _Alloc>
struct _Rope_base 
  : public _Rope_alloc_base<_CharT,_Alloc,
			    _Alloc_traits<_CharT,_Alloc>::_S_instanceless>
{
  typedef _Rope_alloc_base<_CharT,_Alloc,
			    _Alloc_traits<_CharT,_Alloc>::_S_instanceless>
	  _Base;
  typedef typename _Base::allocator_type allocator_type;
  typedef _Rope_RopeRep<_CharT,_Alloc> _RopeRep;
	// The one in _Base may not be visible due to template rules.
  _Rope_base(_RopeRep* __t, const allocator_type& __a) : _Base(__t, __a) {}
  _Rope_base(const allocator_type& __a) : _Base(__a) {}
};    

STL 的 rope 分析(一)</br> STL 的 rope 分析(二)</br> STL 的 rope 分析(三)</br> STL 的 rope 分析(四)</br> STL 的 rope 分析(五)</br> STL 的 rope 分析(六)</br> STL 的 rope 分析(七)</br>