+2005-10-07 Paolo Carlini <pcarlini@suse.de>
+
+ Fix libstdc++/24196 for ext/vstring/rc by returning to the behavior
+ of basic_string pre-2003-06-13; remove fully-dynamic-string stuff.
+ * include/ext/rc_string_base.h (_M_refcopy): Move inside the
+ _Rep class and remove code in macro.
+ (__rc_string_base()): Construct with _S_empty_rep()._M_refcopy().
+ (_M_dispose, _M_leak_hard): Remove code in macro.
+ (_S_construct): Return _S_empty_rep()._M_refcopy() for empty string.
+ (_M_grab): Adjust.
+
+ * include/ext/rc_string_base.h (_Rep::_M_refdata()): Minor tweak,
+ mark throw().
+
2005-10-07 Benjamin Kosnik <bkoz@redhat.com>
* docs/doxygen/user.cfg.in: Update to Doyxygen 1.4.4.
typedef typename _Alloc::template rebind<size_type>::other _Raw_alloc;
_CharT*
- _M_refdata()
+ _M_refdata() throw()
{ return reinterpret_cast<_CharT*>(this + 1); }
+ _CharT*
+ _M_refcopy() throw()
+ {
+ __atomic_add(&_M_refcount, 1);
+ return _M_refdata();
+ } // XXX MT
+
void
_M_set_length(size_type __n)
{
{ return &((reinterpret_cast<_Rep*>(_M_data()))[-1]); }
_CharT*
- _M_refcopy() const throw()
- {
-#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();
- } // XXX MT
-
- _CharT*
_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) const
{
return (!_M_is_leaked() && __alloc1 == __alloc2)
- ? _M_refcopy() : _M_rep()->_M_clone(__alloc1);
+ ? _M_rep()->_M_refcopy() : _M_rep()->_M_clone(__alloc1);
}
void
_M_dispose(const _Alloc& __a)
{
-#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);
+ if (__exchange_and_add(&_M_rep()->_M_refcount, -1) <= 0)
+ _M_rep()->_M_destroy(__a);
} // XXX MT
void
}
__rc_string_base()
-#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
- : _M_dataplus(_S_empty_rep()._M_refdata(), _Alloc()) { }
-#else
- : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { }
-#endif
+ : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { }
+
__rc_string_base(const _Alloc& __a);
__rc_string_base(const __rc_string_base& __rcs);
__rc_string_base<_CharT, _Traits, _Alloc>::
_M_leak_hard()
{
-#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();
_S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
std::input_iterator_tag)
{
-#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__beg == __end && __a == _Alloc())
- return _S_empty_rep()._M_refdata();
-#endif
+ return _S_empty_rep()._M_refcopy();
+
// Avoid reallocation for common case.
_CharT __buf[128];
size_type __len = 0;
_S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a,
std::forward_iterator_tag)
{
-#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__beg == __end && __a == _Alloc())
- return _S_empty_rep()._M_refdata();
-#endif
+ return _S_empty_rep()._M_refcopy();
+
// NB: Not required, but considered best practice.
if (__builtin_expect(__is_null_p(__beg) && __beg != __end, 0))
std::__throw_logic_error(__N("__rc_string_base::"
__rc_string_base<_CharT, _Traits, _Alloc>::
_S_construct(size_type __n, _CharT __c, const _Alloc& __a)
{
-#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__n == 0 && __a == _Alloc())
- return _S_empty_rep()._M_refdata();
-#endif
+ return _S_empty_rep()._M_refcopy();
+
// Check for out_of_range and length_error exceptions.
_Rep* __r = _Rep::_S_create(__n, size_type(0), __a);
if (__n)