STL 的 string 分析(六)

#-string #-STL

函数 find_last_not_of 用来查找当前 basic_string 中从 __pos 往前的位置上第一次出现不属于 __s 到 __s + n 中的元素的位置。函数通过设置 reverse_iterator 将迭代器迭代顺序变为从后往前,然后类似于 find_first_of 中查找那样调用 find_if 查找 __pos(不包括 __pos 所在位置)往前第一次碰到不属于 __s 到 __s + n 中的元素的位置。

template <class _CharT, class _Traits, class _Alloc>
basic_string<_CharT,_Traits,_Alloc>::size_type
basic_string<_CharT,_Traits,_Alloc>
  ::find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const 
{

  const size_type __len = size();

  if (__len < 1)
    return npos;
  else {
    const const_iterator __last = begin() + min(__len - 1, __pos) + 1;
    const const_reverse_iterator __rresult =
      find_if(const_reverse_iterator(__last), rend(),
	      _Not_within_traits<_Traits>(__s, __s + __n));
    return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos;
  }
}

函数 find_last_not_of 用来查找当前 basic_string 中 __pos 往前第一次出现不为 __c 的元素。函数通过设置 reverse_iterator 将迭代器的迭代顺序变成从后往前。然后类似与 find_first_not_of 中那样调用 find_if 进行查找。

template <class _Tp, class _Traits, class _Alloc>
basic_string<_Tp, _Traits, _Alloc>::size_type
basic_string<_Tp, _Traits, _Alloc>
  ::find_last_not_of(_Tp __c, size_type __pos) const 
{
  const size_type __len = size();

  if (__len < 1)
    return npos;
  else {
    const const_iterator __last = begin() + min(__len - 1, __pos) + 1;
    const_reverse_iterator __rresult =
      find_if(const_reverse_iterator(__last), rend(),
	      not1(bind2nd(_Eq_traits<_Traits>(), __c)));
    return __rresult != rend() ? (__rresult.base() - 1) - begin() : npos;
  }
}

函数 find_last_not_of 用来查找当前 basic_string 中 __pos 往前的位置中第一次出现不是 __s 中的元素的位置。调用之前定义的 find_last_not_of 进行查找。

  size_type find_last_not_of(const basic_string& __s, 
			     size_type __pos = npos) const
    { return find_last_not_of(__s.begin(), __pos, __s.size()); }

函数 find_last_not_of 用来查找当前 basic_string 中 __pos 往前的位置中第一次出现不是 __s 中的元素的位置。

  size_type find_last_not_of(const _CharT* __s, size_type __pos = npos) const
    { return find_last_not_of(__s, __pos, _Traits::length(__s)); }

函数 substr 返回由当前 basic_string 中 __pos 所在位置往后的 __n 个元素组成的序列构成的 basic_string 实例。

  basic_string substr(size_type __pos = 0, size_type __n = npos) const {
    if (__pos > size())
      _M_throw_out_of_range();
    return basic_string(_M_start + __pos, 
			_M_start + __pos + min(__n, size() - __pos));
  }

函数 _M_compare 用来比较从 __f1 到 __l1 的元素序列和从 __f2 到 __l2 的序列。令 __f1 到 __l1 的长度为 __n1 ,令 __f2 到 __l2 的长度为 __n2 ,然后调用 _Traits 中的静态成员函数 compare 比较从 __f1 和 __f2 往后的 min(__n1, __n2) 个元素,返回值暂存到 cmp ,如果 cmp 不为 0 ,说明前 min(__n1, __n2) 个元素就可以比较出以上两个序列的大小,如果 cmp 为 0 ,则当 __n1 < __n2 是返回 -1 ,否则如果 __n1 > __n2 返回 1。如果 __n1 == __n2 则返回 0 。

  static int _M_compare(const _CharT* __f1, const _CharT* __l1,
			const _CharT* __f2, const _CharT* __l2) {
    const ptrdiff_t __n1 = __l1 - __f1;
    const ptrdiff_t __n2 = __l2 - __f2;
    const int cmp = _Traits::compare(__f1, __f2, min(__n1, __n2));
    return cmp != 0 ? cmp : (__n1 < __n2 ? -1 : (__n1 > __n2 ? 1 : 0));
  }

函数 compare 用来比较当前 basic_string 和给定 basic_string 的大小。

  int compare(const basic_string& __s) const 
    { return _M_compare(_M_start, _M_finish, __s._M_start, __s._M_finish); }

函数 compare 用来比较当前 basic_string 中 __pos1 往后 __n1 个元素序列和给定 basic_string __s 的大小。

  int compare(size_type __pos1, size_type __n1,
	      const basic_string& __s) const {
    if (__pos1 > size())
      _M_throw_out_of_range();
    return _M_compare(_M_start + __pos1, 
		      _M_start + __pos1 + min(__n1, size() - __pos1),
		      __s._M_start, __s._M_finish);
  }

函数 compare 用来比较当前 basic_string 中 __pos1 往后 __n1 个元素组成的序列和给定 basic_string __s 中 __pos2 往后 __n2 个元素组成的序列的大小。

  int compare(size_type __pos1, size_type __n1,
	      const basic_string& __s,
	      size_type __pos2, size_type __n2) const {
    if (__pos1 > size() || __pos2 > __s.size())
      _M_throw_out_of_range();
    return _M_compare(_M_start + __pos1, 
		      _M_start + __pos1 + min(__n1, size() - __pos1),
		      __s._M_start + __pos2, 
		      __s._M_start + __pos2 + min(__n2, size() - __pos2));
  }

函数 compare 用来比较当前 basic_string 和 __s 的大小。

  int compare(const _CharT* __s) const {
    return _M_compare(_M_start, _M_finish, __s, __s + _Traits::length(__s));
  }

函数 compare 用来比较当前 basic_string 中 __pos1 往后的 __n1 个元素组成的序列和 __s 的大小。

  int compare(size_type __pos1, size_type __n1, const _CharT* __s) const {
    if (__pos1 > size())
      _M_throw_out_of_range();
    return _M_compare(_M_start + __pos1, 
		      _M_start + __pos1 + min(__n1, size() - __pos1),
		      __s, __s + _Traits::length(__s));
  }

函数 compare 用来比较当前 basic_string 中 __pos1 所在位置往后 __n1 个元素组成的序列和 __s 所在位置往后 __n2 个元素组成的序列的大小。

  int compare(size_type __pos1, size_type __n1, const _CharT* __s,
	      size_type __n2) const {
    if (__pos1 > size())
      _M_throw_out_of_range();
    return _M_compare(_M_start + __pos1, 
		      _M_start + __pos1 + min(__n1, size() - __pos1),
		      __s, __s + __n2);
  }

函数 operator+ 返回两个 basic_string __x 和 __y 前后拼接而成的 basic_string 实例。函数中先声明一个 basic_string 的实例 __result,并在构造函数中申请了足够容纳 __x 和 __y 中所有元素的空间,然后将 __x 插入到 __result 尾部,再将 __y 插入到 __result 尾部。函数中没有直接用 __x 的内容来初始化 __result ,是因为那样要进行两次内存的分配,而且其中进行第二次分配是还涉及到元素的移动。

template <class _CharT, class _Traits, class _Alloc>
inline basic_string<_CharT,_Traits,_Alloc>
operator+(const basic_string<_CharT,_Traits,_Alloc>& __x,
	  const basic_string<_CharT,_Traits,_Alloc>& __y)
{
  typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  typedef typename _Str::_Reserve_t _Reserve_t;
  _Reserve_t __reserve;
  _Str __result(__reserve, __x.size() + __y.size(), __x.get_allocator());
  __result.append(__x);
  __result.append(__y);
  return __result;
}

函数 operator+ 将 __s 开始到结束标记所在位置之间的内容和 basic_string __y 中的内容进行拼接,并将拼接而成的内容作为返回值。首先声明一个 basic_string 的实例,并在 __result 中预留足够容纳 __s 和 __y 的空间。再将 __s 中的内容插入到 __reuslt 尾部,接着将 __y 中的内容插入到 __result 尾部。

template <class _CharT, class _Traits, class _Alloc>
inline basic_string<_CharT,_Traits,_Alloc>
operator+(const _CharT* __s,
	  const basic_string<_CharT,_Traits,_Alloc>& __y) {
  typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  typedef typename _Str::_Reserve_t _Reserve_t;
  _Reserve_t __reserve;
  const size_t __n = _Traits::length(__s);
  _Str __result(__reserve, __n + __y.size());
  __result.append(__s, __s + __n);
  __result.append(__y);
  return __result;
}

函数 operator+ 将元素 __c 和 basic_string __y 中的内容进行前后拼接,并将拼接得到的 basic_string 的实例作为返回值返回。

template <class _CharT, class _Traits, class _Alloc>
inline basic_string<_CharT,_Traits,_Alloc>
operator+(_CharT __c,
	  const basic_string<_CharT,_Traits,_Alloc>& __y) {
  typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  typedef typename _Str::_Reserve_t _Reserve_t;
  _Reserve_t __reserve;
  _Str __result(__reserve, 1 + __y.size());
  __result.push_back(__c);
  __result.append(__y);
  return __result;
}

函数 operator+ 将 basic_string __x 和从 __s 开始到结束标记所在位置之间的内容进行拼接,并将拼接而成的 basic_string 实例作为返回值返回。

template <class _CharT, class _Traits, class _Alloc>
inline basic_string<_CharT,_Traits,_Alloc>
operator+(const basic_string<_CharT,_Traits,_Alloc>& __x,
	  const _CharT* __s) {
  typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  typedef typename _Str::_Reserve_t _Reserve_t;
  _Reserve_t __reserve;
  const size_t __n = _Traits::length(__s);
  _Str __result(__reserve, __x.size() + __n, __x.get_allocator());
  __result.append(__x);
  __result.append(__s, __s + __n);
  return __result;
}

函数 operator+ 将 basic_string __x 和元素 __c 进行拼接,并将拼接而成的 basic_string 的实例作为返回值返回。

template <class _CharT, class _Traits, class _Alloc>
inline basic_string<_CharT,_Traits,_Alloc>
operator+(const basic_string<_CharT,_Traits,_Alloc>& __x,
	  const _CharT __c) {
  typedef basic_string<_CharT,_Traits,_Alloc> _Str;
  typedef typename _Str::_Reserve_t _Reserve_t;
  _Reserve_t __reserve;
  _Str __result(__reserve, __x.size() + 1, __x.get_allocator());
  __result.append(__x);
  __result.push_back(__c);
  return __result;
}

函数 operator== 判断两个 basic_string __x 和 __y 是否相等。

template <class _CharT, class _Traits, class _Alloc>
inline bool
operator==(const basic_string<_CharT,_Traits,_Alloc>& __x,
	   const basic_string<_CharT,_Traits,_Alloc>& __y) {
  return __x.size() == __y.size() &&
	 _Traits::compare(__x.data(), __y.data(), __x.size()) == 0;
}

函数 operator== 判断从 __s 开始到结束标记所在位置之间的内容和 basic_string __y 是否相等。

template <class _CharT, class _Traits, class _Alloc>
inline bool
operator==(const _CharT* __s,
	   const basic_string<_CharT,_Traits,_Alloc>& __y) {
  size_t __n = _Traits::length(__s);
  return __n == __y.size() && _Traits::compare(__s, __y.data(), __n) == 0;
}

函数 operator== 判断 basic_string 和从 __s 开始到结束标记所在位置之间的内容是否相等。

template <class _CharT, class _Traits, class _Alloc>
inline bool
operator==(const basic_string<_CharT,_Traits,_Alloc>& __x,
	   const _CharT* __s) {
  size_t __n = _Traits::length(__s);
  return __x.size() == __n && _Traits::compare(__x.data(), __s, __n) == 0;
}

函数 operator< 判断 basic_string __x 是否小于 basic_string __y 。

template <class _CharT, class _Traits, class _Alloc>
inline bool
operator<(const basic_string<_CharT,_Traits,_Alloc>& __x,
	  const basic_string<_CharT,_Traits,_Alloc>& __y) {
  return basic_string<_CharT,_Traits,_Alloc>
    ::_M_compare(__x.begin(), __x.end(), __y.begin(), __y.end()) < 0;
}

函数 operator< 判断从 __s 开始到结束标记所在位置之间的内容是否小于 basic_string __y 。

template <class _CharT, class _Traits, class _Alloc>
inline bool
operator<(const _CharT* __s,
	  const basic_string<_CharT,_Traits,_Alloc>& __y) {
  size_t __n = _Traits::length(__s);
  return basic_string<_CharT,_Traits,_Alloc>
    ::_M_compare(__s, __s + __n, __y.begin(), __y.end()) < 0;
}

函数 operator< 判断 basic_string __x 是否小于从 __s 开始到结束标记所在位置之间的内容。

template <class _CharT, class _Traits, class _Alloc>
inline bool
operator<(const basic_string<_CharT,_Traits,_Alloc>& __x,
	  const _CharT* __s) {
  size_t __n = _Traits::length(__s);
  return basic_string<_CharT,_Traits,_Alloc>
    ::_M_compare(__x.begin(), __x.end(), __s, __s + __n) < 0;
}

string 文件中还重载了 operator« 和 operator» ,并定义了 getline 函数。其中 operator» 用输入流中的内容来更新指定的 basic_string 实例。 operator« 用输出流将指定的 basic_string 实例中的内容输出。getline 函数用指定的输入流中的内容更新指定的 basic_string 实例。

函数 _S_string_copy 将指定 basic_string 中的前 __n 个元素复制到 __buf 开始的位置。

template <class _CharT, class _Traits, class _Alloc>
void _S_string_copy(const basic_string<_CharT,_Traits,_Alloc>& __s,
		    _CharT* __buf,
		    size_t __n)
{
  if (__n > 0) {
    __n = min(__n - 1, __s.size());
    copy(__s.begin(), __s.begin() + __n, __buf);
    _Traits::assign(__buf[__n],
		    basic_string<_CharT,_Traits,_Alloc>::_M_null());
  }
}

函数 __stl_string_hash 用来获取指定 basic_string 的 hash 值。

template <class _CharT, class _Traits, class _Alloc>
size_t __stl_string_hash(const basic_string<_CharT,_Traits,_Alloc>& __s) {
  unsigned long __h = 0;
  for (basic_string<_CharT,_Traits,_Alloc>::const_iterator __i = __s.begin();
       __i != __s.end();
       ++__i)
    __h = 5*__h + *__i;
  return size_t(__h);
}

hash 可以看成一个函数对象,它的实例的 operator() 函数可以用来获取指定 basic_string 的 hash 值。

template <class _CharT, class _Traits, class _Alloc>
struct hash<basic_string<_CharT,_Traits,_Alloc> > {
  size_t operator()(const basic_string<_CharT,_Traits,_Alloc>& __s) const
    { return __stl_string_hash(__s); }
};

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