⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basic_string.tcc

📁 俄罗斯高人Mamaich的Pocket gcc编译器(运行在PocketPC上)的全部源代码。
💻 TCC
📖 第 1 页 / 共 3 页
字号:
			   typename iterator_traits<const _CharT*>::iterator_category());     }    template<typename _CharT, typename _Traits, typename _Alloc>    void    basic_string<_CharT, _Traits, _Alloc>::_Rep::    _M_destroy(const _Alloc& __a) throw ()    {      size_type __size = sizeof(_Rep) + (_M_capacity + 1) * sizeof(_CharT);      _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);    }  template<typename _CharT, typename _Traits, typename _Alloc>    void    basic_string<_CharT, _Traits, _Alloc>::_M_leak_hard()    {      if (_M_rep()->_M_is_shared()) 	_M_mutate(0, 0, 0);      _M_rep()->_M_set_leaked();    }  // _M_mutate and, below, _M_clone, include, in the same form, an exponential  // growth policy, necessary to meet amortized linear time requirements of  // the library: see http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.  // The policy is active for allocations requiring an amount of memory above  // system pagesize. This is consistent with the requirements of the standard:  // see, f.i., http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html  template<typename _CharT, typename _Traits, typename _Alloc>    void    basic_string<_CharT, _Traits, _Alloc>::    _M_mutate(size_type __pos, size_type __len1, size_type __len2)    {      size_type       __old_size = this->size();      const size_type __new_size = __old_size + __len2 - __len1;      const _CharT*        __src = _M_data()  + __pos + __len1;      const size_type __how_much = __old_size - __pos - __len1;            if (_M_rep()->_M_is_shared() || __new_size > capacity())	{	  // Must reallocate.	  allocator_type __a = get_allocator();	  // See below (_S_create) for the meaning and value of these	  // constants.	  const size_type __pagesize = 4096;	  const size_type __malloc_header_size = 4 * sizeof (void*);	  // The biggest string which fits in a memory page	  const size_type __page_capacity = (__pagesize - __malloc_header_size					     - sizeof(_Rep) - sizeof(_CharT)) 	    				     / sizeof(_CharT);	  _Rep* __r;	  if (__new_size > capacity() && __new_size > __page_capacity)	    // Growing exponentially.	    __r = _Rep::_S_create(__new_size > 2*capacity() ?				  __new_size : 2*capacity(), __a);	  else	    __r = _Rep::_S_create(__new_size, __a);	  try 	    {	      if (__pos)		traits_type::copy(__r->_M_refdata(), _M_data(), __pos);	      if (__how_much)		traits_type::copy(__r->_M_refdata() + __pos + __len2, 				  __src, __how_much);	    }	  catch(...) 	    { 	      __r->_M_dispose(get_allocator()); 	      __throw_exception_again;	    }	  _M_rep()->_M_dispose(__a);	  _M_data(__r->_M_refdata());      }      else if (__how_much && __len1 != __len2)	{	  // Work in-place	  traits_type::move(_M_data() + __pos + __len2, __src, __how_much);	}      _M_rep()->_M_set_sharable();      _M_rep()->_M_length = __new_size;      _M_data()[__new_size] = _Rep::_S_terminal; // grrr. (per 21.3.4)    // You cannot leave those LWG people alone for a second.    }    template<typename _CharT, typename _Traits, typename _Alloc>    void    basic_string<_CharT, _Traits, _Alloc>::reserve(size_type __res)    {      if (__res > this->capacity() || _M_rep()->_M_is_shared())        {	  if (__res > this->max_size())	    __throw_length_error("basic_string::reserve");	  // Make sure we don't shrink below the current size	  if (__res < this->size())	    __res = this->size();	  allocator_type __a = get_allocator();	  _CharT* __tmp = _M_rep()->_M_clone(__a, __res - this->size());	  _M_rep()->_M_dispose(__a);	  _M_data(__tmp);        }    }    template<typename _CharT, typename _Traits, typename _Alloc>    void basic_string<_CharT, _Traits, _Alloc>::swap(basic_string& __s)    {      if (_M_rep()->_M_is_leaked()) 	_M_rep()->_M_set_sharable();      if (__s._M_rep()->_M_is_leaked()) 	__s._M_rep()->_M_set_sharable();      if (this->get_allocator() == __s.get_allocator())	{	  _CharT* __tmp = _M_data();	  _M_data(__s._M_data());	  __s._M_data(__tmp);	}      // The code below can usually be optimized away.      else 	{	  basic_string __tmp1(_M_ibegin(), _M_iend(), __s.get_allocator());	  basic_string __tmp2(__s._M_ibegin(), __s._M_iend(), 			      this->get_allocator());	  *this = __tmp2;	  __s = __tmp1;	}    }  template<typename _CharT, typename _Traits, typename _Alloc>    typename basic_string<_CharT, _Traits, _Alloc>::_Rep*    basic_string<_CharT, _Traits, _Alloc>::_Rep::    _S_create(size_t __capacity, const _Alloc& __alloc)    {      typedef basic_string<_CharT, _Traits, _Alloc> __string_type;#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS      // 83.  String::npos vs. string::max_size()      if (__capacity > _S_max_size)#else      if (__capacity == npos)#endif	__throw_length_error("basic_string::_S_create");      // NB: Need an array of char_type[__capacity], plus a      // terminating null char_type() element, plus enough for the      // _Rep data structure. Whew. Seemingly so needy, yet so elemental.      size_t __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);      // The standard places no restriction on allocating more memory      // than is strictly needed within this layer at the moment or as      // requested by an explicit application call to reserve().  Many      // malloc implementations perform quite poorly when an      // application attempts to allocate memory in a stepwise fashion      // growing each allocation size by only 1 char.  Additionally,      // it makes little sense to allocate less linear memory than the      // natural blocking size of the malloc implementation.      // Unfortunately, we would need a somewhat low-level calculation      // with tuned parameters to get this perfect for any particular      // malloc implementation.  Fortunately, generalizations about      // common features seen among implementations seems to suffice.      // __pagesize need not match the actual VM page size for good      // results in practice, thus we pick a common value on the low      // side.  __malloc_header_size is an estimate of the amount of      // overhead per memory allocation (in practice seen N * sizeof      // (void*) where N is 0, 2 or 4).  According to folklore,      // picking this value on the high side is better than      // low-balling it (especially when this algorithm is used with      // malloc implementations that allocate memory blocks rounded up      // to a size which is a power of 2).      const size_t __pagesize = 4096; // must be 2^i * __subpagesize      const size_t __subpagesize = 128; // should be >> __malloc_header_size      const size_t __malloc_header_size = 4 * sizeof (void*);      if ((__size + __malloc_header_size) > __pagesize)	{	  size_t __extra =	    (__pagesize - ((__size + __malloc_header_size) % __pagesize))	    % __pagesize;	  __capacity += __extra / sizeof(_CharT);	  __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);	}      else if (__size > __subpagesize)	{	  size_t __extra =	    (__subpagesize - ((__size + __malloc_header_size) % __subpagesize))	    % __subpagesize;	  __capacity += __extra / sizeof(_CharT);	  __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);	}      // NB: Might throw, but no worries about a leak, mate: _Rep()      // does not throw.      void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);      _Rep *__p = new (__place) _Rep;      __p->_M_capacity = __capacity;      __p->_M_set_sharable();  // One reference.      __p->_M_length = 0;      return __p;    }  template<typename _CharT, typename _Traits, typename _Alloc>    _CharT*    basic_string<_CharT, _Traits, _Alloc>::_Rep::    _M_clone(const _Alloc& __alloc, size_type __res)    {      // Requested capacity of the clone.      const size_type __requested_cap = _M_length + __res;      // See above (_S_create) for the meaning and value of these constants.      const size_type __pagesize = 4096;      const size_type __malloc_header_size = 4 * sizeof (void*);      // The biggest string which fits in a memory page.      const size_type __page_capacity =        (__pagesize - __malloc_header_size - sizeof(_Rep) - sizeof(_CharT))        / sizeof(_CharT);      _Rep* __r;      if (__requested_cap > _M_capacity && __requested_cap > __page_capacity)        // Growing exponentially.        __r = _Rep::_S_create(__requested_cap > 2*_M_capacity ?                              __requested_cap : 2*_M_capacity, __alloc);      else        __r = _Rep::_S_create(__requested_cap, __alloc);            if (_M_length)	{	  try 	    { traits_type::copy(__r->_M_refdata(), _M_refdata(), _M_length); }	  catch(...)  	    { 	      __r->_M_destroy(__alloc); 	      __throw_exception_again;	    }	}      __r->_M_length = _M_length;      __r->_M_refdata()[_M_length] = _Rep::_S_terminal;      return __r->_M_refdata();    }    template<typename _CharT, typename _Traits, typename _Alloc>    void    basic_string<_CharT, _Traits, _Alloc>::resize(size_type __n, _CharT __c)    {      if (__n > max_size())	__throw_length_error("basic_string::resize");      size_type __size = this->size();      if (__size < __n)	this->append(__n - __size, __c);      else if (__n < __size)	this->erase(__n);      // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)    }  // This is the general replace helper, which currently gets instantiated both  // for input iterators and reverse iterators. It buffers internally and then  // calls _M_replace_safe.  template<typename _CharT, typename _Traits, typename _Alloc>    template<typename _InputIter>      basic_string<_CharT, _Traits, _Alloc>&      basic_string<_CharT, _Traits, _Alloc>::      _M_replace(iterator __i1, iterator __i2, _InputIter __k1, 		 _InputIter __k2, input_iterator_tag)      {	// Save concerned source string data in a temporary.	basic_string __s(__k1, __k2);	return _M_replace_safe(__i1, __i2, __s._M_ibegin(), __s._M_iend());      }  // This is a special replace helper, which does not buffer internally  // and can be used in "safe" situations involving forward iterators,  // i.e., when source and destination ranges are known to not overlap.  template<typename _CharT, typename _Traits, typename _Alloc>    template<typename _ForwardIter>      basic_string<_CharT, _Traits, _Alloc>&      basic_string<_CharT, _Traits, _Alloc>::      _M_replace_safe(iterator __i1, iterator __i2, _ForwardIter __k1, 		      _ForwardIter __k2)      {	size_type __dnew = static_cast<size_type>(std::distance(__k1, __k2));	size_type __dold = __i2 - __i1;	size_type __dmax = this->max_size();	if (__dmax <= __dnew)	  __throw_length_error("basic_string::_M_replace");	size_type __off = __i1 - _M_ibegin();	_M_mutate(__off, __dold, __dnew);	// Invalidated __i1, __i2        if (__dnew)	  _S_copy_chars(_M_data() + __off, __k1, __k2);	return *this;      }  template<typename _CharT, typename _Traits, typename _Alloc>    basic_string<_CharT, _Traits, _Alloc>&    basic_string<_CharT, _Traits, _Alloc>::    replace(size_type __pos1, size_type __n1, const basic_string& __str,	    size_type __pos2, size_type __n2)    {      const size_type __strsize = __str.size();      if (__pos2 > __strsize)	__throw_out_of_range("basic_string::replace");      const bool __testn2 = __n2 < __strsize - __pos2;      const size_type __foldn2 = __testn2 ? __n2 : __strsize - __pos2;      return this->replace(__pos1, __n1,			   __str._M_data() + __pos2, __foldn2);          }  template<typename _CharT, typename _Traits, typename _Alloc>    basic_string<_CharT, _Traits, _Alloc>&    basic_string<_CharT, _Traits, _Alloc>::    append(const basic_string& __str)    {      // Iff appending itself, string needs to pre-reserve the      // correct size so that _M_mutate does not clobber the      // iterators formed here.      size_type __size = __str.size();      size_type __len = __size + this->size();      if (__len > this->capacity())	this->reserve(__len);      return _M_replace_safe(_M_iend(), _M_iend(), __str._M_ibegin(),			     __str._M_iend());    }  template<typename _CharT, typename _Traits, typename _Alloc>    basic_string<_CharT, _Traits, _Alloc>&    basic_string<_CharT, _Traits, _Alloc>::    append(const basic_string& __str, size_type __pos, size_type __n)    {      // Iff appending itself, string needs to pre-reserve the      // correct size so that _M_mutate does not clobber the      // iterators formed here.      size_type __len = std::min(size_type(__str.size() - __pos),				 __n) + this->size();      if (__len > this->capacity())	this->reserve(__len);      return _M_replace_safe(_M_iend(), _M_iend(), __str._M_check(__pos),			     __str._M_fold(__pos, __n));    }  template<typename _CharT, typename _Traits, typename _Alloc>    basic_string<_CharT, _Traits, _Alloc>&    basic_string<_CharT, _Traits, _Alloc>::    append(const _CharT* __s, size_type __n)    {      size_type __len = __n + this->size();      if (__len > this->capacity())	this->reserve(__len);      return _M_replace_safe(_M_iend(), _M_iend(), __s, __s + __n);    }  template<typename _CharT, typename _Traits, typename _Alloc>    basic_string<_CharT, _Traits, _Alloc>&    basic_string<_CharT, _Traits, _Alloc>::    append(size_type __n, _CharT __c)    {      size_type __len = __n + this->size();      if (__len > this->capacity())	this->reserve(__len);       return this->replace(_M_iend(), _M_iend(), __n, __c);    }  template<typename _CharT, typename _Traits, typename _Alloc>    basic_string<_CharT, _Traits, _Alloc>    operator+(const _CharT* __lhs,	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)    {      typedef basic_string<_CharT, _Traits, _Alloc> __string_type;      typedef typename __string_type::size_type	  __size_type;      __size_type __len = _Traits::length(__lhs);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -