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

📄 rc_string_base.h

📁 linux下编程用 编译软件
💻 H
📖 第 1 页 / 共 2 页
字号:
// Reference-counted versatile string base -*- C++ -*-// Copyright (C) 2005, 2006 Free Software Foundation, Inc.//// This file is part of the GNU ISO C++ Library.  This library is free// software; you can redistribute it and/or modify it under the// terms of the GNU General Public License as published by the// Free Software Foundation; either version 2, or (at your option)// any later version.// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.// You should have received a copy of the GNU General Public License along// with this library; see the file COPYING.  If not, write to the Free// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,// USA.// As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License./** @file ext/rc_string_base.h *  This file is a GNU extension to the Standard C++ Library. *  This is an internal header file, included by other library headers. *  You should not attempt to use it directly. */#ifndef _RC_STRING_BASE_H#define _RC_STRING_BASE_H 1#include <bits/atomicity.h>namespace __gnu_cxx{  /**   *  @if maint   *  Documentation?  What's that?   *  Nathan Myers <ncm@cantrip.org>.   *   *  A string looks like this:   *   *  @code   *                                        [_Rep]   *                                        _M_length   *   [__rc_string_base<char_type>]        _M_capacity   *   _M_dataplus                          _M_refcount   *   _M_p ---------------->               unnamed array of char_type   *  @endcode   *   *  Where the _M_p points to the first character in the string, and   *  you cast it to a pointer-to-_Rep and subtract 1 to get a   *  pointer to the header.   *   *  This approach has the enormous advantage that a string object   *  requires only one allocation.  All the ugliness is confined   *  within a single pair of inline functions, which each compile to   *  a single "add" instruction: _Rep::_M_refdata(), and   *  __rc_string_base::_M_rep(); and the allocation function which gets a   *  block of raw bytes and with room enough and constructs a _Rep   *  object at the front.   *   *  The reason you want _M_data pointing to the character array and   *  not the _Rep is so that the debugger can see the string   *  contents. (Probably we should add a non-inline member to get   *  the _Rep for the debugger to use, so users can check the actual   *  string length.)   *   *  Note that the _Rep object is a POD so that you can have a   *  static "empty string" _Rep object already "constructed" before   *  static constructors have run.  The reference-count encoding is   *  chosen so that a 0 indicates one reference, so you never try to   *  destroy the empty-string _Rep object.   *   *  All but the last paragraph is considered pretty conventional   *  for a C++ string implementation.   *  @endif  */ template<typename _CharT, typename _Traits, typename _Alloc>    class __rc_string_base    : protected __vstring_utility<_CharT, _Traits, _Alloc>    {    public:      typedef _Traits					    traits_type;      typedef typename _Traits::char_type		    value_type;      typedef _Alloc					    allocator_type;      typedef __vstring_utility<_CharT, _Traits, _Alloc>    _Util_Base;      typedef typename _Util_Base::_CharT_alloc_type        _CharT_alloc_type;      typedef typename _CharT_alloc_type::size_type	    size_type;    private:      // _Rep: string representation      //   Invariants:      //   1. String really contains _M_length + 1 characters: due to 21.3.4      //      must be kept null-terminated.      //   2. _M_capacity >= _M_length      //      Allocated memory is always (_M_capacity + 1) * sizeof(_CharT).      //   3. _M_refcount has three states:      //      -1: leaked, one reference, no ref-copies allowed, non-const.      //       0: one reference, non-const.      //     n>0: n + 1 references, operations require a lock, const.      //   4. All fields == 0 is an empty string, given the extra storage      //      beyond-the-end for a null terminator; thus, the shared      //      empty string representation needs no constructor.      struct _Rep      {	union	{	  struct	  {	    size_type	    _M_length;	    size_type	    _M_capacity;	    _Atomic_word    _M_refcount;	  }                 _M_info;	  	  // Only for alignment purposes.	  _CharT            _M_align;	};	typedef typename _Alloc::template rebind<_Rep>::other _Rep_alloc_type; 	_CharT*	_M_refdata() throw()	{ return reinterpret_cast<_CharT*>(this + 1); }	_CharT*	_M_refcopy() throw()	{	  __atomic_add(&_M_info._M_refcount, 1);	  return _M_refdata();	}  // XXX MT		void	_M_set_length(size_type __n)	{ 	  _M_info._M_refcount = 0;  // One reference.	  _M_info._M_length = __n;	  // grrr. (per 21.3.4)	  // You cannot leave those LWG people alone for a second.	  traits_type::assign(_M_refdata()[__n], _CharT());	}	// Create & Destroy	static _Rep*	_S_create(size_type, size_type, const _Alloc&);	void	_M_destroy(const _Alloc&) throw();	_CharT*	_M_clone(const _Alloc&, size_type __res = 0);      };      struct _Rep_empty      : public _Rep      {	_CharT              _M_terminal;      };      static _Rep_empty     _S_empty_rep;      // The maximum number of individual char_type elements of an      // individual string is determined by _S_max_size. This is the      // value that will be returned by max_size().  (Whereas npos      // is the maximum number of bytes the allocator can allocate.)      // If one was to divvy up the theoretical largest size string,      // with a terminating character and m _CharT elements, it'd      // look like this:      // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)      // Solving for m:      // m = ((npos - sizeof(_Rep)) / sizeof(_CharT)) - 1      // In addition, this implementation quarters this amount.      enum { _S_max_size = (((static_cast<size_type>(-1) - sizeof(_Rep))			     / sizeof(_CharT)) - 1) / 4 };      // Data Member (private):      mutable typename _Util_Base::template _Alloc_hider<_Alloc>  _M_dataplus;      void      _M_data(_CharT* __p)      { _M_dataplus._M_p = __p; }      _Rep*      _M_rep() const      { return &((reinterpret_cast<_Rep*>(_M_data()))[-1]); }      _CharT*      _M_grab(const _Alloc& __alloc) const      {	return (!_M_is_leaked() && _M_get_allocator() == __alloc)	        ? _M_rep()->_M_refcopy() : _M_rep()->_M_clone(__alloc);      }      void      _M_dispose()      {	if (__exchange_and_add(&_M_rep()->_M_info._M_refcount, -1) <= 0)	  _M_rep()->_M_destroy(_M_get_allocator());      }  // XXX MT      bool      _M_is_leaked() const      { return _M_rep()->_M_info._M_refcount < 0; }      void      _M_set_sharable()      { _M_rep()->_M_info._M_refcount = 0; }      void      _M_leak_hard();      // _S_construct_aux is used to implement the 21.3.1 para 15 which      // requires special behaviour if _InIterator is an integral type      template<typename _InIterator>        static _CharT*        _S_construct_aux(_InIterator __beg, _InIterator __end,			 const _Alloc& __a, __false_type)	{          typedef typename iterator_traits<_InIterator>::iterator_category _Tag;          return _S_construct(__beg, __end, __a, _Tag());	}      template<typename _InIterator>        static _CharT*        _S_construct_aux(_InIterator __beg, _InIterator __end,			 const _Alloc& __a, __true_type)	{ return _S_construct(static_cast<size_type>(__beg),			      static_cast<value_type>(__end), __a); }      template<typename _InIterator>        static _CharT*        _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a)	{	  typedef typename std::__is_integer<_InIterator>::__type _Integral;	  return _S_construct_aux(__beg, __end, __a, _Integral());        }      // For Input Iterators, used in istreambuf_iterators, etc.      template<typename _InIterator>        static _CharT*         _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,		      std::input_iterator_tag);            // For forward_iterators up to random_access_iterators, used for      // string::iterator, _CharT*, etc.      template<typename _FwdIterator>        static _CharT*        _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a,		     std::forward_iterator_tag);      static _CharT*      _S_construct(size_type __req, _CharT __c, const _Alloc& __a);    public:      size_type      _M_max_size() const      { return size_type(_S_max_size); }      _CharT*      _M_data() const      { return _M_dataplus._M_p; }      size_type      _M_length() const      { return _M_rep()->_M_info._M_length; }      size_type      _M_capacity() const      { return _M_rep()->_M_info._M_capacity; }      bool      _M_is_shared() const      { return _M_rep()->_M_info._M_refcount > 0; }      void      _M_set_leaked()      { _M_rep()->_M_info._M_refcount = -1; }      void      _M_leak()    // for use in begin() & non-const op[]      {	if (!_M_is_leaked())	  _M_leak_hard();      }      void      _M_set_length(size_type __n)      { _M_rep()->_M_set_length(__n); }      __rc_string_base()      : _M_dataplus(_Alloc(), _S_empty_rep._M_refcopy()) { }      __rc_string_base(const _Alloc& __a);      __rc_string_base(const __rc_string_base& __rcs);      __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a);      template<typename _InputIterator>        __rc_string_base(_InputIterator __beg, _InputIterator __end,			 const _Alloc& __a);      ~__rc_string_base()      { _M_dispose(); }            allocator_type&      _M_get_allocator()      { return _M_dataplus; }      const allocator_type&      _M_get_allocator() const      { return _M_dataplus; }      void      _M_swap(__rc_string_base& __rcs);      void      _M_assign(const __rc_string_base& __rcs);      void      _M_reserve(size_type __res);      void      _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,		size_type __len2);            void      _M_erase(size_type __pos, size_type __n);      bool      _M_compare(const __rc_string_base&) const      { return false; }    };  template<typename _CharT, typename _Traits, typename _Alloc>    typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep_empty    __rc_string_base<_CharT, _Traits, _Alloc>::_S_empty_rep;  template<typename _CharT, typename _Traits, typename _Alloc>    typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep*    __rc_string_base<_CharT, _Traits, _Alloc>::_Rep::    _S_create(size_type __capacity, size_type __old_capacity,	      const _Alloc& __alloc)    {

⌨️ 快捷键说明

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