111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Reference-counted versatile string base -*- C++ -*- 211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 2005-2014 Free Software Foundation, Inc. 411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is part of the GNU ISO C++ Library. This library is free 611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// software; you can redistribute it and/or modify it under the 711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// terms of the GNU General Public License as published by the 811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Free Software Foundation; either version 3, or (at your option) 911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// any later version. 1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This library is distributed in the hope that it will be useful, 1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// but WITHOUT ANY WARRANTY; without even the implied warranty of 1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// GNU General Public License for more details. 1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Under Section 7 of GPL version 3, you are granted additional 1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// permissions described in the GCC Runtime Library Exception, version 1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 3.1, as published by the Free Software Foundation. 1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// You should have received a copy of the GNU General Public License and 2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// a copy of the GCC Runtime Library Exception along with this program; 2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// <http://www.gnu.org/licenses/>. 2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/** @file ext/rc_string_base.h 2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This is an internal header file, included by other library headers. 2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Do not attempt to use it directly. @headername{ext/vstring.h} 2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _RC_STRING_BASE_H 3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _RC_STRING_BASE_H 1 3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <ext/atomicity.h> 3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <bits/stl_iterator_base_funcs.h> 3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{ 3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_BEGIN_NAMESPACE_VERSION 3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert /** 4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Documentation? What's that? 4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Nathan Myers <ncm@cantrip.org>. 4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * A string looks like this: 4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * @code 4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * [_Rep] 4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * _M_length 4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * [__rc_string_base<char_type>] _M_capacity 5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * _M_dataplus _M_refcount 5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * _M_p ----------------> unnamed array of char_type 5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * @endcode 5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Where the _M_p points to the first character in the string, and 5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * you cast it to a pointer-to-_Rep and subtract 1 to get a 5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * pointer to the header. 5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This approach has the enormous advantage that a string object 5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * requires only one allocation. All the ugliness is confined 6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * within a single pair of inline functions, which each compile to 6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * a single @a add instruction: _Rep::_M_refdata(), and 6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * __rc_string_base::_M_rep(); and the allocation function which gets a 6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * block of raw bytes and with room enough and constructs a _Rep 6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * object at the front. 6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * The reason you want _M_data pointing to the character array and 6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * not the _Rep is so that the debugger can see the string 6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * contents. (Probably we should add a non-inline member to get 6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * the _Rep for the debugger to use, so users can check the actual 7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * string length.) 7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Note that the _Rep object is a POD so that you can have a 7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * static <em>empty string</em> _Rep object already @a constructed before 7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * static constructors have run. The reference-count encoding is 7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * chosen so that a 0 indicates one reference, so you never try to 7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * destroy the empty-string _Rep object. 7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * 7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * All but the last paragraph is considered pretty conventional 7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * for a C++ string implementation. 8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */ 8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert class __rc_string_base 8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : protected __vstring_utility<_CharT, _Traits, _Alloc> 8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Traits traits_type; 8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename _Traits::char_type value_type; 8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef _Alloc allocator_type; 8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base; 9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type; 9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename _CharT_alloc_type::size_type size_type; 9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private: 9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // _Rep: string representation 9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Invariants: 9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 1. String really contains _M_length + 1 characters: due to 21.3.4 9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // must be kept null-terminated. 9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 2. _M_capacity >= _M_length 10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Allocated memory is always (_M_capacity + 1) * sizeof(_CharT). 10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 3. _M_refcount has three states: 10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // -1: leaked, one reference, no ref-copies allowed, non-const. 10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 0: one reference, non-const. 10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // n>0: n + 1 references, operations require a lock, const. 10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 4. All fields == 0 is an empty string, given the extra storage 10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // beyond-the-end for a null terminator; thus, the shared 10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // empty string representation needs no constructor. 10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Rep 10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert union 11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct 11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_type _M_length; 11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_type _M_capacity; 11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Atomic_word _M_refcount; 11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } _M_info; 11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Only for alignment purposes. 12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT _M_align; 12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename _Alloc::template rebind<_Rep>::other _Rep_alloc_type; 12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* 12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refdata() throw() 12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return reinterpret_cast<_CharT*>(this + 1); } 12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* 13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcopy() throw() 13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __atomic_add_dispatch(&_M_info._M_refcount, 1); 13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _M_refdata(); 13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } // XXX MT 13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_set_length(size_type __n) 13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_info._M_refcount = 0; // One reference. 14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_info._M_length = __n; 14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // grrr. (per 21.3.4) 14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // You cannot leave those LWG people alone for a second. 14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert traits_type::assign(_M_refdata()[__n], _CharT()); 14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Create & Destroy 14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _Rep* 14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_create(size_type, size_type, const _Alloc&); 14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy(const _Alloc&) throw(); 15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* 15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_clone(const _Alloc&, size_type __res = 0); 15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert struct _Rep_empty 15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : public _Rep 15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT _M_terminal; 16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _Rep_empty _S_empty_rep; 16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The maximum number of individual char_type elements of an 16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // individual string is determined by _S_max_size. This is the 16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // value that will be returned by max_size(). (Whereas npos 16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // is the maximum number of bytes the allocator can allocate.) 16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // If one was to divvy up the theoretical largest size string, 17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // with a terminating character and m _CharT elements, it'd 17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // look like this: 17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT) 17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // + sizeof(_Rep) - 1 17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // (NB: last two terms for rounding reasons, see _M_create below) 17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Solving for m: 17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // m = ((npos - 2 * sizeof(_Rep) + 1) / sizeof(_CharT)) - 1 17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // In addition, this implementation halves this amount. 17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert enum { _S_max_size = (((static_cast<size_type>(-1) - 2 * sizeof(_Rep) 17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert + 1) / sizeof(_CharT)) - 1) / 2 }; 18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Data Member (private): 18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert mutable typename _Util_Base::template _Alloc_hider<_Alloc> _M_dataplus; 18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data(_CharT* __p) 18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_dataplus._M_p = __p; } 18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* 18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_rep() const 19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return &((reinterpret_cast<_Rep*>(_M_data()))[-1]); } 19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* 19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_grab(const _Alloc& __alloc) const 19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return (!_M_is_leaked() && _M_get_allocator() == __alloc) 19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ? _M_rep()->_M_refcopy() : _M_rep()->_M_clone(__alloc); 19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose() 20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Be race-detector-friendly. For more info see bits/c++config. 20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_rep()->_M_info. 20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount); 20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__exchange_and_add_dispatch(&_M_rep()->_M_info._M_refcount, 20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert -1) <= 0) 20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_rep()->_M_info. 20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_refcount); 21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_rep()->_M_destroy(_M_get_allocator()); 21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } // XXX MT 21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_is_leaked() const 21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_rep()->_M_info._M_refcount < 0; } 21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_set_sharable() 22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_rep()->_M_info._M_refcount = 0; } 22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_leak_hard(); 22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // _S_construct_aux is used to implement the 21.3.1 para 15 which 22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // requires special behaviour if _InIterator is an integral type 22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _InIterator> 22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _CharT* 22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct_aux(_InIterator __beg, _InIterator __end, 23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Alloc& __a, std::__false_type) 23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename iterator_traits<_InIterator>::iterator_category _Tag; 23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _S_construct(__beg, __end, __a, _Tag()); 23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // _GLIBCXX_RESOLVE_LIB_DEFECTS 23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 438. Ambiguity in the "do the right thing" clause 23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _Integer> 23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _CharT* 24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct_aux(_Integer __beg, _Integer __end, 24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Alloc& __a, std::__true_type) 24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _S_construct_aux_2(static_cast<size_type>(__beg), 24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __end, __a); } 24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _CharT* 24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct_aux_2(size_type __req, _CharT __c, const _Alloc& __a) 24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _S_construct(__req, __c, __a); } 24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _InIterator> 25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _CharT* 25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a) 25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typedef typename std::__is_integer<_InIterator>::__type _Integral; 25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _S_construct_aux(__beg, __end, __a, _Integral()); 25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // For Input Iterators, used in istreambuf_iterators, etc. 25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _InIterator> 25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _CharT* 26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::input_iterator_tag); 26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // For forward_iterators up to random_access_iterators, used for 26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // string::iterator, _CharT*, etc. 26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _FwdIterator> 26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _CharT* 26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct(_FwdIterator __beg, _FwdIterator __end, const _Alloc& __a, 26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::forward_iterator_tag); 26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert static _CharT* 27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct(size_type __req, _CharT __c, const _Alloc& __a); 27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public: 27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_type 27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_max_size() const 27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return size_type(_S_max_size); } 27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* 27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data() const 28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_dataplus._M_p; } 28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_type 28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_length() const 28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_rep()->_M_info._M_length; } 28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_type 28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_capacity() const 28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_rep()->_M_info._M_capacity; } 28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_is_shared() const 29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_rep()->_M_info._M_refcount > 0; } 29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_set_leaked() 29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_rep()->_M_info._M_refcount = -1; } 29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_leak() // for use in begin() & non-const op[] 30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (!_M_is_leaked()) 30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_leak_hard(); 30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_set_length(size_type __n) 30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_rep()->_M_set_length(__n); } 30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base() 31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_dataplus(_S_empty_rep._M_refcopy()) { } 31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base(const _Alloc& __a); 31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base(const __rc_string_base& __rcs); 31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L 31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base(__rc_string_base&& __rcs) 31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_dataplus(__rcs._M_dataplus) 31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __rcs._M_data(_S_empty_rep._M_refcopy()); } 32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a); 32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _InputIterator> 32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base(_InputIterator __beg, _InputIterator __end, 32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Alloc& __a); 32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ~__rc_string_base() 32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_dispose(); } 33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert allocator_type& 33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_allocator() 33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_dataplus; } 33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const allocator_type& 33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_allocator() const 33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return _M_dataplus; } 33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_swap(__rc_string_base& __rcs); 34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_assign(const __rc_string_base& __rcs); 34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_reserve(size_type __res); 34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, 35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_type __len2); 35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_erase(size_type __pos, size_type __n); 35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_clear() 35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { _M_erase(size_type(0), _M_length()); } 35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert bool 36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_compare(const __rc_string_base&) const 36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { return false; } 36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert }; 36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep_empty 36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>::_S_empty_rep; 36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert typename __rc_string_base<_CharT, _Traits, _Alloc>::_Rep* 37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: 37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_create(size_type __capacity, size_type __old_capacity, 37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Alloc& __alloc) 37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // _GLIBCXX_RESOLVE_LIB_DEFECTS 37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 83. String::npos vs. string::max_size() 37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__capacity > size_type(_S_max_size)) 37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::__throw_length_error(__N("__rc_string_base::_Rep::_S_create")); 37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The standard places no restriction on allocating more memory 38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // than is strictly needed within this layer at the moment or as 38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // requested by an explicit application call to reserve(). 38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Many malloc implementations perform quite poorly when an 38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // application attempts to allocate memory in a stepwise fashion 38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // growing each allocation size by only 1 char. Additionally, 38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // it makes little sense to allocate less linear memory than the 38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // natural blocking size of the malloc implementation. 38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Unfortunately, we would need a somewhat low-level calculation 38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // with tuned parameters to get this perfect for any particular 39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // malloc implementation. Fortunately, generalizations about 39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // common features seen among implementations seems to suffice. 39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // __pagesize need not match the actual VM page size for good 39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // results in practice, thus we pick a common value on the low 39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // side. __malloc_header_size is an estimate of the amount of 39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // overhead per memory allocation (in practice seen N * sizeof 39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // (void*) where N is 0, 2 or 4). According to folklore, 39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // picking this value on the high side is better than 39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // low-balling it (especially when this algorithm is used with 40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // malloc implementations that allocate memory blocks rounded up 40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // to a size which is a power of 2). 40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __pagesize = 4096; 40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __malloc_header_size = 4 * sizeof(void*); 40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // The below implements an exponential growth policy, necessary to 40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // meet amortized linear time requirements of the library: see 40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. 40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) 40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __capacity = 2 * __old_capacity; 41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Never allocate a string bigger than _S_max_size. 41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__capacity > size_type(_S_max_size)) 41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __capacity = size_type(_S_max_size); 41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // NB: Need an array of char_type[__capacity], plus a terminating 41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // null char_type() element, plus enough for the _Rep data structure, 41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // plus sizeof(_Rep) - 1 to upper round to a size multiple of 41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // sizeof(_Rep). 42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Whew. Seemingly so needy, yet so elemental. 42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_type __size = ((__capacity + 1) * sizeof(_CharT) 42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert + 2 * sizeof(_Rep) - 1); 42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __adj_size = __size + __malloc_header_size; 42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__adj_size > __pagesize && __capacity > __old_capacity) 42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __extra = __pagesize - __adj_size % __pagesize; 42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __capacity += __extra / sizeof(_CharT); 42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__capacity > size_type(_S_max_size)) 43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __capacity = size_type(_S_max_size); 43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __size = (__capacity + 1) * sizeof(_CharT) + 2 * sizeof(_Rep) - 1; 43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // NB: Might throw, but no worries about a leak, mate: _Rep() 43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // does not throw. 43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* __place = _Rep_alloc_type(__alloc).allocate(__size / sizeof(_Rep)); 43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* __p = new (__place) _Rep; 43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __p->_M_info._M_capacity = __capacity; 43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __p; 44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: 44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_destroy(const _Alloc& __a) throw () 44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __size = ((_M_info._M_capacity + 1) * sizeof(_CharT) 44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert + 2 * sizeof(_Rep) - 1); 44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep_alloc_type(__a).deallocate(this, __size / sizeof(_Rep)); 45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* 45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>::_Rep:: 45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_clone(const _Alloc& __alloc, size_type __res) 45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Requested capacity of the clone. 45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __requested_cap = _M_info._M_length + __res; 45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* __r = _Rep::_S_create(__requested_cap, _M_info._M_capacity, 46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __alloc); 46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_info._M_length) 46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base::_S_copy(__r->_M_refdata(), _M_refdata(), _M_info._M_length); 46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r->_M_set_length(_M_info._M_length); 46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __r->_M_refdata(); 46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base(const _Alloc& __a) 47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_dataplus(__a, _S_construct(size_type(), _CharT(), __a)) { } 47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base(const __rc_string_base& __rcs) 47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_dataplus(__rcs._M_get_allocator(), 47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rcs._M_grab(__rcs._M_get_allocator())) { } 47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base(size_type __n, _CharT __c, const _Alloc& __a) 48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_dataplus(__a, _S_construct(__n, __c, __a)) { } 48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _InputIterator> 48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base(_InputIterator __beg, _InputIterator __end, 48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const _Alloc& __a) 49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert : _M_dataplus(__a, _S_construct(__beg, __end, __a)) { } 49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_leak_hard() 49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_is_shared()) 49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_erase(0, 0); 49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_set_leaked(); 50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // NB: This is the special case for Input Iterators, used in 50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // istreambuf_iterators, etc. 50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Input Iterators have a cost structure very different from 50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // pointers, calling for a different coding style. 50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _InIterator> 50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* 50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::input_iterator_tag) 51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__beg == __end && __a == _Alloc()) 51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _S_empty_rep._M_refcopy(); 51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Avoid reallocation for common case. 51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT __buf[128]; 51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_type __len = 0; 51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert while (__beg != __end && __len < sizeof(__buf) / sizeof(_CharT)) 52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __buf[__len++] = *__beg; 52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ++__beg; 52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); 52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_copy(__r->_M_refdata(), __buf, __len); 52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __try 52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert while (__beg != __end) 52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__len == __r->_M_info._M_capacity) 53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Allocate more space. 53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); 53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_copy(__another->_M_refdata(), __r->_M_refdata(), __len); 53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r->_M_destroy(__a); 53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r = __another; 53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r->_M_refdata()[__len++] = *__beg; 53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert ++__beg; 54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __catch(...) 54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r->_M_destroy(__a); 54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_exception_again; 54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r->_M_set_length(__len); 54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __r->_M_refdata(); 54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _InIterator> 55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* 55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, 55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::forward_iterator_tag) 55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__beg == __end && __a == _Alloc()) 55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _S_empty_rep._M_refcopy(); 56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // NB: Not required, but considered best practice. 56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__is_null_pointer(__beg) && __beg != __end) 56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::__throw_logic_error(__N("__rc_string_base::" 56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert "_S_construct null not valid")); 56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __dnew = static_cast<size_type>(std::distance(__beg, 56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __end)); 56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Check for out_of_range and length_error exceptions. 56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* __r = _Rep::_S_create(__dnew, size_type(0), __a); 57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __try 57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { __rc_string_base::_S_copy_chars(__r->_M_refdata(), __beg, __end); } 57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __catch(...) 57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r->_M_destroy(__a); 57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __throw_exception_again; 57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r->_M_set_length(__dnew); 57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __r->_M_refdata(); 57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* 58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _S_construct(size_type __n, _CharT __c, const _Alloc& __a) 58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__n == 0 && __a == _Alloc()) 58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return _S_empty_rep._M_refcopy(); 58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Check for out_of_range and length_error exceptions. 59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); 59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__n) 59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base::_S_assign(__r->_M_refdata(), __n, __c); 59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __r->_M_set_length(__n); 59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return __r->_M_refdata(); 59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_swap(__rc_string_base& __rcs) 60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_is_leaked()) 60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_set_sharable(); 60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__rcs._M_is_leaked()) 60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rcs._M_set_sharable(); 60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* __tmp = _M_data(); 60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data(__rcs._M_data()); 61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rcs._M_data(__tmp); 61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // _GLIBCXX_RESOLVE_LIB_DEFECTS 61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // 431. Swapping containers with unequal allocators. 61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::__alloc_swap<allocator_type>::_S_do_it(_M_get_allocator(), 61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rcs._M_get_allocator()); 61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_assign(const __rc_string_base& __rcs) 62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_rep() != __rcs._M_rep()) 62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* __tmp = __rcs._M_grab(_M_get_allocator()); 62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose(); 62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data(__tmp); 62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_reserve(size_type __res) 63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Make sure we don't shrink below the current size. 63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__res < _M_length()) 63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __res = _M_length(); 63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__res != _M_capacity() || _M_is_shared()) 64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(), 64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __res - _M_length()); 64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose(); 64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data(__tmp); 64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, 65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert size_type __len2) 65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __how_much = _M_length() - __pos - __len1; 65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* __r = _Rep::_S_create(_M_length() + __len2 - __len1, 65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_capacity(), _M_get_allocator()); 65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__pos) 66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_S_copy(__r->_M_refdata(), _M_data(), __pos); 66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__s && __len2) 66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_S_copy(__r->_M_refdata() + __pos, __s, __len2); 66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__how_much) 66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_S_copy(__r->_M_refdata() + __pos + __len2, 66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data() + __pos + __len1, __how_much); 66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose(); 66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data(__r->_M_refdata()); 67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<typename _CharT, typename _Traits, typename _Alloc> 67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert void 67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<_CharT, _Traits, _Alloc>:: 67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_erase(size_type __pos, size_type __n) 67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __new_size = _M_length() - __n; 67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert const size_type __how_much = _M_length() - __pos - __n; 67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_is_shared()) 68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Must reallocate. 68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _Rep* __r = _Rep::_S_create(__new_size, _M_capacity(), 68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_get_allocator()); 68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__pos) 68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_S_copy(__r->_M_refdata(), _M_data(), __pos); 68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (__how_much) 68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_S_copy(__r->_M_refdata() + __pos, 69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data() + __pos + __n, __how_much); 69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 69211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_dispose(); 69311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data(__r->_M_refdata()); 69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert else if (__how_much && __n) 69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert // Work in-place. 69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert this->_S_move(_M_data() + __pos, 69911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_data() + __pos + __n, __how_much); 70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_rep()->_M_set_length(__new_size); 70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<char, std::char_traits<char>, 70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::allocator<char> >:: 70911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_compare(const __rc_string_base& __rcs) const 71011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_rep() == __rcs._M_rep()) 71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 71511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 71611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _GLIBCXX_USE_WCHAR_T 71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert template<> 71811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert inline bool 71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert __rc_string_base<wchar_t, std::char_traits<wchar_t>, 72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert std::allocator<wchar_t> >:: 72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert _M_compare(const __rc_string_base& __rcs) const 72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert { 72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert if (_M_rep() == __rcs._M_rep()) 72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return true; 72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert return false; 72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert } 72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif 72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_END_NAMESPACE_VERSION 73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // namespace 73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert 73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* _RC_STRING_BASE_H */ 733