aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2005-02-20 15:45:53 +0000
committerPaolo Carlini <pcarlini@suse.de>2005-02-20 15:45:53 +0000
commit19f41d1ed1957a0bd1c4ca352507d848fe1137f7 (patch)
treec930cc73e6f63a20165fa1c6eea29a948596c0c8
parent950a219e8d41b708c99e21bb4922e96d8af61f0b (diff)
2005-02-20 Paolo Carlini <pcarlini@suse.de>
* include/ext/rc_string.h: Add __rc_string(const __rc_string&); restore the _M_data(_CharT*); add _M_length(), _M_capacity(), _M_set_length(); minor clean-ups. (__rc_string(_CharT*, const _Alloc&), _M_data_pointer): Remove. (_M_assign): Tweak to take a const __rc_string&. (_M_swap): Tweak to take a __rc_string&. (_Rep::_M_is_shared, _M_is_leaked, _M_set_shared, _M_set_leaked): Move out to __rc_string. * include/bits/basic_string.h: Tweak consistently with the above. * include/bits/basic_string.tcc: Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/libstdcxx_so_7-branch@95303 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog.libstdcxx_so_7-branch13
-rw-r--r--libstdc++-v3/include/bits/basic_string.h25
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc42
-rw-r--r--libstdc++-v3/include/ext/rc_string.h330
4 files changed, 218 insertions, 192 deletions
diff --git a/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch b/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch
index adc0adfc4bd..691722f7d32 100644
--- a/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch
+++ b/libstdc++-v3/ChangeLog.libstdcxx_so_7-branch
@@ -1,3 +1,16 @@
+2005-02-20 Paolo Carlini <pcarlini@suse.de>
+
+ * include/ext/rc_string.h: Add __rc_string(const __rc_string&);
+ restore the _M_data(_CharT*); add _M_length(), _M_capacity(),
+ _M_set_length(); minor clean-ups.
+ (__rc_string(_CharT*, const _Alloc&), _M_data_pointer): Remove.
+ (_M_assign): Tweak to take a const __rc_string&.
+ (_M_swap): Tweak to take a __rc_string&.
+ (_Rep::_M_is_shared, _M_is_leaked, _M_set_shared, _M_set_leaked):
+ Move out to __rc_string.
+ * include/bits/basic_string.h: Tweak consistently with the above.
+ * include/bits/basic_string.tcc: Likewise.
+
2005-02-18 Paolo Carlini <pcarlini@suse.de>
* acinclude.m4 ([GLIBCXX_ENABLE_STRING]): New, allows to
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 1d9a4211c99..c2db351492f 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -134,7 +134,7 @@ namespace std
iterator
_M_iend() const
- { return iterator(this->_M_data() + this->_M_rep()->_M_length); }
+ { return iterator(this->_M_data() + this->_M_length()); }
public:
// Construct/copy/destroy:
@@ -160,9 +160,7 @@ namespace std
* @param str Source string.
*/
basic_string(const basic_string& __str)
- : __string_base(__str._M_grab(_Alloc(__str.get_allocator()),
- __str.get_allocator()),
- __str.get_allocator()) { }
+ : __string_base(__str) { }
/**
* @brief Construct string as copy of a substring.
@@ -349,13 +347,13 @@ namespace std
/// null-termination.
size_type
size() const
- { return this->_M_rep()->_M_length; }
+ { return this->_M_length(); }
/// Returns the number of characters in the string, not including any
/// null-termination.
size_type
length() const
- { return this->_M_rep()->_M_length; }
+ { return this->_M_length(); }
/// Returns the size() of the largest possible %string.
size_type
@@ -395,7 +393,7 @@ namespace std
*/
size_type
capacity() const
- { return this->_M_rep()->_M_capacity; }
+ { return this->_M_capacity(); }
/**
* @brief Attempt to preallocate enough memory for specified number of
@@ -612,10 +610,10 @@ namespace std
push_back(_CharT __c)
{
const size_type __len = 1 + this->size();
- if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
+ if (__len > this->capacity() || this->_M_is_shared())
this->reserve(__len);
traits_type::assign(this->_M_data()[this->size()], __c);
- this->_M_rep()->_M_set_length(__len);
+ this->_M_set_length(__len);
}
/**
@@ -851,7 +849,7 @@ namespace std
_GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
const size_type __pos = __p - _M_ibegin();
_M_replace_aux(__pos, size_type(0), size_type(1), __c);
- this->_M_rep()->_M_set_leaked();
+ this->_M_set_leaked();
return _M_ibegin() + __pos;
}
@@ -892,7 +890,7 @@ namespace std
&& __position < _M_iend());
const size_type __pos = __position - _M_ibegin();
this->_M_mutate(__pos, size_type(1), size_type(0));
- this->_M_rep()->_M_set_leaked();
+ this->_M_set_leaked();
return _M_ibegin() + __pos;
}
@@ -912,7 +910,7 @@ namespace std
&& __last <= _M_iend());
const size_type __pos = __first - _M_ibegin();
this->_M_mutate(__pos, __last - __first, size_type(0));
- this->_M_rep()->_M_set_leaked();
+ this->_M_set_leaked();
return _M_ibegin() + __pos;
}
@@ -1181,8 +1179,7 @@ namespace std
basic_string&
_M_replace_dispatch(iterator __i1, iterator __i2, _Integer __n,
_Integer __val, __true_type)
- { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1,
- __n, __val); }
+ { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }
template<class _InputIterator>
basic_string&
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 59bfa60c683..967a88cea5c 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -56,11 +56,7 @@ namespace std
basic_string<_CharT, _Traits, _Alloc>::
assign(const basic_string& __str)
{
- if (this->_M_rep() != __str._M_rep())
- {
- const allocator_type __a = this->get_allocator();
- this->_M_assign(__str._M_grab(__a, __str.get_allocator()));
- }
+ this->_M_assign(__str);
return *this;
}
@@ -71,7 +67,7 @@ namespace std
{
__glibcxx_requires_string_len(__s, __n);
_M_check_length(this->size(), __n, "basic_string::assign");
- if (_M_disjunct(__s) || this->_M_rep()->_M_is_shared())
+ if (_M_disjunct(__s) || this->_M_is_shared())
return _M_replace_safe(size_type(0), this->size(), __s, __n);
else
{
@@ -81,7 +77,7 @@ namespace std
this->_S_copy(this->_M_data(), __s, __n);
else if (__pos)
this->_S_move(this->_M_data(), __s, __n);
- this->_M_rep()->_M_set_length(__n);
+ this->_M_set_length(__n);
return *this;
}
}
@@ -95,10 +91,10 @@ namespace std
{
_M_check_length(size_type(0), __n, "basic_string::append");
const size_type __len = __n + this->size();
- if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
+ if (__len > this->capacity() || this->_M_is_shared())
this->reserve(__len);
this->_S_assign(this->_M_data() + this->size(), __n, __c);
- this->_M_rep()->_M_set_length(__len);
+ this->_M_set_length(__len);
}
return *this;
}
@@ -113,7 +109,7 @@ namespace std
{
_M_check_length(size_type(0), __n, "basic_string::append");
const size_type __len = __n + this->size();
- if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
+ if (__len > this->capacity() || this->_M_is_shared())
{
if (_M_disjunct(__s))
this->reserve(__len);
@@ -125,7 +121,7 @@ namespace std
}
}
this->_S_copy(this->_M_data() + this->size(), __s, __n);
- this->_M_rep()->_M_set_length(__len);
+ this->_M_set_length(__len);
}
return *this;
}
@@ -139,11 +135,11 @@ namespace std
if (__size)
{
const size_type __len = __size + this->size();
- if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
+ if (__len > this->capacity() || this->_M_is_shared())
this->reserve(__len);
this->_S_copy(this->_M_data() + this->size(), __str._M_data(),
__size);
- this->_M_rep()->_M_set_length(__len);
+ this->_M_set_length(__len);
}
return *this;
}
@@ -158,11 +154,11 @@ namespace std
if (__n)
{
const size_type __len = __n + this->size();
- if (__len > this->capacity() || this->_M_rep()->_M_is_shared())
+ if (__len > this->capacity() || this->_M_is_shared())
this->reserve(__len);
this->_S_copy(this->_M_data() + this->size(),
__str._M_data() + __pos, __n);
- this->_M_rep()->_M_set_length(__len);
+ this->_M_set_length(__len);
}
return *this;
}
@@ -175,7 +171,7 @@ namespace std
__glibcxx_requires_string_len(__s, __n);
_M_check(__pos, "basic_string::insert");
_M_check_length(size_type(0), __n, "basic_string::insert");
- if (_M_disjunct(__s) || this->_M_rep()->_M_is_shared())
+ if (_M_disjunct(__s) || this->_M_is_shared())
return _M_replace_safe(__pos, size_type(0), __s, __n);
else
{
@@ -209,7 +205,7 @@ namespace std
__n1 = _M_limit(__pos, __n1);
_M_check_length(__n1, __n2, "basic_string::replace");
bool __left;
- if (_M_disjunct(__s) || this->_M_rep()->_M_is_shared())
+ if (_M_disjunct(__s) || this->_M_is_shared())
return _M_replace_safe(__pos, __n1, __s, __n2);
else if ((__left = __s + __n2 <= this->_M_data() + __pos)
|| this->_M_data() + __pos + __n1 <= __s)
@@ -235,7 +231,7 @@ namespace std
basic_string<_CharT, _Traits, _Alloc>::
reserve(size_type __res)
{
- if (__res != this->capacity() || this->_M_rep()->_M_is_shared())
+ if (__res != this->capacity() || this->_M_is_shared())
{
// Make sure we don't shrink below the current size
if (__res < this->size())
@@ -249,12 +245,12 @@ namespace std
basic_string<_CharT, _Traits, _Alloc>::
swap(basic_string& __s)
{
- if (this->_M_rep()->_M_is_leaked())
- this->_M_rep()->_M_set_sharable();
- if (__s._M_rep()->_M_is_leaked())
- __s._M_rep()->_M_set_sharable();
+ if (this->_M_is_leaked())
+ this->_M_set_sharable();
+ if (__s._M_is_leaked())
+ __s._M_set_sharable();
if (this->get_allocator() == __s.get_allocator())
- this->_M_swap(__s._M_data_pointer());
+ this->_M_swap(__s);
// The code below can usually be optimized away.
else
{
diff --git a/libstdc++-v3/include/ext/rc_string.h b/libstdc++-v3/include/ext/rc_string.h
index 9044bda57ac..e8622bf5730 100644
--- a/libstdc++-v3/include/ext/rc_string.h
+++ b/libstdc++-v3/include/ext/rc_string.h
@@ -95,10 +95,6 @@ namespace __gnu_cxx
: public __string_utility<_CharT, _Traits, _Alloc>
{
public:
- using __string_utility<_CharT, _Traits, _Alloc>::_S_assign;
- using __string_utility<_CharT, _Traits, _Alloc>::_S_copy;
- using __string_utility<_CharT, _Traits, _Alloc>::_S_move;
-
// Types:
typedef _Traits traits_type;
typedef typename _Traits::char_type value_type;
@@ -117,7 +113,7 @@ namespace __gnu_cxx
// m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
// In addition, this implementation quarters this amount.
static const size_type _S_max_size;
- static const _CharT _S_terminal;
+ static const _CharT _S_terminal;
private:
// _Rep: string representation
@@ -141,33 +137,18 @@ namespace __gnu_cxx
typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
- bool
- _M_is_leaked() const
- { return _M_refcount < 0; }
-
- bool
- _M_is_shared() const
- { return _M_refcount > 0; }
-
- void
- _M_set_leaked()
- { _M_refcount = -1; }
-
- void
- _M_set_sharable()
- { _M_refcount = 0; }
-
- _CharT*
+ _CharT*
_M_refdata()
{ return reinterpret_cast<_CharT*>(this + 1); }
void
_M_set_length(size_type __n)
{
- _M_set_sharable(); // One reference.
+ _M_refcount = 0; // One reference.
_M_length = __n;
- _M_refdata()[__n] = _S_terminal; // grrr. (per 21.3.4)
+ // grrr. (per 21.3.4)
// You cannot leave those LWG people alone for a second.
+ traits_type::assign(_M_refdata()[__n], _S_terminal);
}
// Create & Destroy
@@ -195,106 +176,49 @@ namespace __gnu_cxx
_CharT* _M_p; // The actual data.
};
- // Data Members (private):
+ // Data Member (private):
mutable _Alloc_hider _M_dataplus;
- public:
+ static _Rep_empty&
+ _S_empty_rep()
+ {
+ static _Rep_empty _Empty_rep;
+ return _Empty_rep;
+ }
+
_CharT*
- _M_data() const
- { return _M_dataplus._M_p; }
+ _M_data(_CharT* __p)
+ { return (_M_dataplus._M_p = __p); }
- _CharT**
- _M_data_pointer() const
- { return &_M_dataplus._M_p; }
-
_Rep*
_M_rep() const
- { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }
+ { return &((reinterpret_cast<_Rep*>(_M_data()))[-1]); }
- void
- _M_dispose(const _Alloc& __a)
+ _CharT*
+ _M_refcopy() const throw()
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(_M_rep() != &_S_empty_rep(), false))
#endif
- if (__exchange_and_add(&_M_rep()->_M_refcount, -1) <= 0)
- _M_rep()->_M_destroy(__a);
+ __atomic_add(&_M_rep()->_M_refcount, 1);
+ return _M_data();
} // XXX MT
_CharT*
_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) const
{
- return (!_M_rep()->_M_is_leaked() && __alloc1 == __alloc2)
+ return (!_M_is_leaked() && __alloc1 == __alloc2)
? _M_refcopy() : _M_rep()->_M_clone(__alloc1);
}
void
- _M_leak() // for use in begin() & non-const op[]
- {
- if (!_M_rep()->_M_is_leaked())
- _M_leak_hard();
- }
-
- __rc_string()
-#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
- : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
-#else
- : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { }
-#endif
- __rc_string(const _Alloc& __a);
-
- __rc_string(_CharT* __ptr, const _Alloc& __a);
-
- __rc_string(size_type __n, _CharT __c, const _Alloc& __a);
-
- template<typename _InputIterator>
- __rc_string(_InputIterator __beg, _InputIterator __end,
- const _Alloc& __a);
-
- ~__rc_string()
- { _M_dispose(_M_get_allocator()); }
-
- allocator_type
- _M_get_allocator() const
- { return _M_dataplus; }
-
- void
- _M_assign(_CharT* __ptr)
- {
- _M_dispose(_M_get_allocator());
- _M_dataplus._M_p = __ptr;
- }
-
- void
- _M_swap(_CharT** __ptr)
- {
- _CharT* __tmp = _M_data();
- _M_dataplus._M_p = *__ptr;
- *__ptr = __tmp;
- }
-
- void
- _M_reserve(size_type __res);
-
- void
- _M_mutate(size_type __pos, size_type __len1, size_type __len2);
-
- private:
- static _Rep_empty&
- _S_empty_rep()
- {
- static _Rep_empty _Empty_rep;
- return _Empty_rep;
- }
-
- _CharT*
- _M_refcopy() const throw()
+ _M_dispose(const _Alloc& __a)
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(_M_rep() != &_S_empty_rep(), false))
#endif
- __atomic_add(&_M_rep()->_M_refcount, 1);
- return _M_data();
+ if (__exchange_and_add(&_M_rep()->_M_refcount, -1) <= 0)
+ _M_rep()->_M_destroy(__a);
} // XXX MT
void
@@ -341,6 +265,86 @@ namespace __gnu_cxx
static _CharT*
_S_construct(size_type __req, _CharT __c, const _Alloc& __a);
+
+ public:
+ _CharT*
+ _M_data() const
+ { return _M_dataplus._M_p; }
+
+ size_type
+ _M_length() const
+ { return _M_rep()->_M_length; }
+
+ size_type
+ _M_capacity() const
+ { return _M_rep()->_M_capacity; }
+
+ bool
+ _M_is_shared() const
+ { return _M_rep()->_M_refcount > 0; }
+
+ bool
+ _M_is_leaked() const
+ { return _M_rep()->_M_refcount < 0; }
+
+ void
+ _M_set_sharable()
+ { _M_rep()->_M_refcount = 0; }
+
+ void
+ _M_set_leaked()
+ { _M_rep()->_M_refcount = -1; }
+
+ void
+ _M_set_length(size_type __n)
+ { _M_rep()->_M_set_length(__n); }
+
+ void
+ _M_leak() // for use in begin() & non-const op[]
+ {
+ if (!_M_is_leaked())
+ _M_leak_hard();
+ }
+
+ __rc_string()
+#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
+#else
+ : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { }
+#endif
+ __rc_string(const _Alloc& __a);
+
+ __rc_string(const __rc_string& __rcs);
+
+ __rc_string(size_type __n, _CharT __c, const _Alloc& __a);
+
+ template<typename _InputIterator>
+ __rc_string(_InputIterator __beg, _InputIterator __end,
+ const _Alloc& __a);
+
+ ~__rc_string()
+ { _M_dispose(_M_get_allocator()); }
+
+ allocator_type
+ _M_get_allocator() const
+ { return _M_dataplus; }
+
+ void
+ _M_swap(__rc_string& __rcs)
+ {
+ _CharT* __tmp = _M_data();
+ _M_data(__rcs._M_data());
+ __rcs._M_data(__tmp);
+ }
+
+ void
+ _M_assign(const __rc_string& __rcs);
+
+ void
+ _M_reserve(size_type __res);
+
+ void
+ _M_mutate(size_type __pos, size_type __len1, size_type __len2);
};
template<typename _CharT, typename _Traits, typename _Alloc>
@@ -429,7 +433,7 @@ namespace __gnu_cxx
_M_destroy(const _Alloc& __a) throw ()
{
const size_type __size = sizeof(_Rep) +
- (this->_M_capacity + 1) * sizeof(_CharT);
+ (_M_capacity + 1) * sizeof(_CharT);
_Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
}
@@ -439,13 +443,13 @@ namespace __gnu_cxx
_M_clone(const _Alloc& __alloc, size_type __res)
{
// Requested capacity of the clone.
- const size_type __requested_cap = this->_M_length + __res;
- _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity,
- __alloc);
- if (this->_M_length)
- _S_copy(__r->_M_refdata(), this->_M_refdata(), this->_M_length);
+ const size_type __requested_cap = _M_length + __res;
+ _Rep* __r = _Rep::_S_create(__requested_cap, _M_capacity, __alloc);
+
+ if (_M_length)
+ _S_copy(__r->_M_refdata(), _M_refdata(), _M_length);
- __r->_M_set_length(this->_M_length);
+ __r->_M_set_length(_M_length);
return __r->_M_refdata();
}
@@ -456,8 +460,10 @@ namespace __gnu_cxx
template<typename _CharT, typename _Traits, typename _Alloc>
__rc_string<_CharT, _Traits, _Alloc>::
- __rc_string(_CharT* __ptr, const _Alloc& __a)
- : _M_dataplus(__ptr, __a) { }
+ __rc_string(const __rc_string& __rcs)
+ : _M_dataplus(__rcs._M_grab(_Alloc(__rcs._M_get_allocator()),
+ __rcs._M_get_allocator()),
+ __rcs._M_get_allocator()) { }
template<typename _CharT, typename _Traits, typename _Alloc>
__rc_string<_CharT, _Traits, _Alloc>::
@@ -475,47 +481,17 @@ namespace __gnu_cxx
template<typename _CharT, typename _Traits, typename _Alloc>
void
__rc_string<_CharT, _Traits, _Alloc>::
- _M_reserve(size_type __res)
+ _M_leak_hard()
{
- const allocator_type __a = _M_get_allocator();
- _CharT* __tmp = _M_rep()->_M_clone(__a, __res - _M_rep()->_M_length);
- _M_dispose(__a);
- _M_dataplus._M_p = __tmp;
+#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
+ if (_M_rep() == &_S_empty_rep())
+ return;
+#endif
+ if (_M_is_shared())
+ _M_mutate(0, 0, 0);
+ _M_set_leaked();
}
- template<typename _CharT, typename _Traits, typename _Alloc>
- void
- __rc_string<_CharT, _Traits, _Alloc>::
- _M_mutate(size_type __pos, size_type __len1, size_type __len2)
- {
- const size_type __old_size = _M_rep()->_M_length;
- const size_type __new_size = __old_size + __len2 - __len1;
- const size_type __how_much = __old_size - __pos - __len1;
-
- if (__new_size > _M_rep()->_M_capacity || _M_rep()->_M_is_shared())
- {
- // Must reallocate.
- const allocator_type __a = _M_dataplus;
- _Rep* __r = _Rep::_S_create(__new_size, _M_rep()->_M_capacity, __a);
-
- if (__pos)
- _S_copy(__r->_M_refdata(), _M_data(), __pos);
- if (__how_much)
- _S_copy(__r->_M_refdata() + __pos + __len2,
- _M_data() + __pos + __len1, __how_much);
-
- _M_dispose(__a);
- _M_dataplus._M_p = __r->_M_refdata();
- }
- else if (__how_much && __len1 != __len2)
- {
- // Work in-place.
- _S_move(_M_data() + __pos + __len2,
- _M_data() + __pos + __len1, __how_much);
- }
- _M_rep()->_M_set_length(__new_size);
- }
-
// NB: This is the special case for Input Iterators, used in
// istreambuf_iterators, etc.
// Input Iterators have a cost structure very different from
@@ -618,15 +594,59 @@ namespace __gnu_cxx
template<typename _CharT, typename _Traits, typename _Alloc>
void
__rc_string<_CharT, _Traits, _Alloc>::
- _M_leak_hard()
+ _M_assign(const __rc_string& __rcs)
{
-#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
- if (_M_rep() == &_S_empty_rep())
- return;
-#endif
- if (_M_rep()->_M_is_shared())
- _M_mutate(0, 0, 0);
- _M_rep()->_M_set_leaked();
+ if (_M_rep() != __rcs._M_rep())
+ {
+ const allocator_type __a = _M_get_allocator();
+ _CharT* __tmp = __rcs._M_grab(__a, __rcs._M_get_allocator());
+ _M_dispose(__a);
+ _M_data(__tmp);
+ }
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void
+ __rc_string<_CharT, _Traits, _Alloc>::
+ _M_reserve(size_type __res)
+ {
+ const allocator_type __a = _M_get_allocator();
+ _CharT* __tmp = _M_rep()->_M_clone(__a, __res - _M_length());
+ _M_dispose(__a);
+ _M_data(__tmp);
+ }
+
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ void
+ __rc_string<_CharT, _Traits, _Alloc>::
+ _M_mutate(size_type __pos, size_type __len1, size_type __len2)
+ {
+ const size_type __old_size = _M_length();
+ const size_type __new_size = __old_size + __len2 - __len1;
+ const size_type __how_much = __old_size - __pos - __len1;
+
+ if (__new_size > _M_capacity() || _M_is_shared())
+ {
+ // Must reallocate.
+ const allocator_type __a = _M_get_allocator();
+ _Rep* __r = _Rep::_S_create(__new_size, _M_capacity(), __a);
+
+ if (__pos)
+ _S_copy(__r->_M_refdata(), _M_data(), __pos);
+ if (__how_much)
+ _S_copy(__r->_M_refdata() + __pos + __len2,
+ _M_data() + __pos + __len1, __how_much);
+
+ _M_dispose(__a);
+ _M_data(__r->_M_refdata());
+ }
+ else if (__how_much && __len1 != __len2)
+ {
+ // Work in-place.
+ _S_move(_M_data() + __pos + __len2,
+ _M_data() + __pos + __len1, __how_much);
+ }
+ _M_rep()->_M_set_length(__new_size);
}
} // namespace __gnu_cxx