]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
vstring.h (__versa_string<>::operator+, [...]): Move out of line...
authorPaolo Carlini <pcarlini@suse.de>
Mon, 5 Dec 2005 00:32:31 +0000 (00:32 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 5 Dec 2005 00:32:31 +0000 (00:32 +0000)
2005-12-04  Paolo Carlini  <pcarlini@suse.de>

* include/ext/vstring.h (__versa_string<>::operator+, all
versions): Move out of line...
* include/ext/vstring.tcc (__versa_string<>::operator+): ...
here; consistently use reserve for the benefit of sso_string_base;
prefer push_back to single-char append when appropriate.

* include/ext/vstring.h (__versa_string<>::push_back): Don't
call _M_reserve, _M_mutate instead.
(reserve): Just forward to _M_reserve.
* include/ext/vstring.tcc (__versa_string<>::_M_reserve): Remove.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve): Also
do the initial checks (first on length, in case __res == capacity).
* include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve:
Likewise; don't call _M_set_length unnecessarily.

2005-12-04  Paolo Carlini  <pcarlini@suse.de>

* include/ext/vstring.h (__versa_string<>::_M_append): New.
(append(const __versa_string&), append(const __versa_string&,
size_type, size_type), append(const _CharT*, size_type),
append(const _CharT*)): Use it.
(append(size_type, _CharT)): Delegate to _M_replace_aux.
(assign(const __versa_string&, size_type, size_type),
assign(const _CharT*), replace(size_type, size_type,
const _CharT*, size_type)): Forward to _M_replace.
* include/ext/vstring.tcc (__versa_string<>::_M_append):
Define, core append functionality.
(_M_replace): Simplify, move __s == 0 case to _M_replace_aux.
(_M_replace_aux): Reorganize, don't call _M_replace.

2005-12-04  Paolo Carlini  <pcarlini@suse.de>

* include/ext/vstring.tcc (__versa_string<>::_M_replace):
Perform _M_check_length at the beginning and remove it from ...
(replace, _M_replace_dispatch, _M_replace_aux, assign): ... here.
(assign): Now move inline.
(resize): Don't call _M_check_length redundantly, append does.

2005-12-04  Paolo Carlini  <pcarlini@suse.de>

* include/ext/sso_string_base.h (__sso_string_base<>::_M_get_allocator):
Add non const version.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_get_allocator):
Likewise.

* include/ext/sso_string_base.h (__sso_string_base<>::_M_erase): Add.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_erase): Likewise.
(_M_leak_hard): Use it.
* include/ext/vstring.h (__versa_string<>::clear, erase, all
versions): Use it.
* include/ext/vstring.tcc (__versa_string<>::resize): Likewise.

* include/ext/vstring.h (__versa_string<>::_M_replace_safe):
Remove.
* include/ext/vstring.h (__versa_string<>::_M_replace): New, does
the in-place work or delegates to _M_mutate in case of reallocation.
* include/ext/vstring.tcc (__versa_string<>::_M_replace_safe):
Remove.
* include/ext/vstring.tcc (__versa_string<>::_M_replace): Define.
(assign, replace, _M_replace_dispatch, _M_replace_aux): Use it.
* include/ext/sso_string_base.h (__sso_string_base<>::_M_mutate):
Change to manage only reallocations.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_mutate):
Likewise.

* include/ext/vstring.h (__versa_string<>::insert(size_type,
const __versa_string&), insert(size_type, const __versa_string&,
size_type, size_type), insert(size_type, const _CharT*, size_type),
insert(size_type, const _CharT*)): Delegate to replace.

* include/ext/vstring.h (__versa_string<>::reserve): Move out of
line.
* include/ext/vstring.tcc (__versa_string<>::reserve): Do the
checks and call _M_reserve.
* include/ext/vstring.h (__versa_string<>::append): Call _M_reserve
instead of reserve.
* include/ext/vstring.tcc (__versa_string<>::append, all versions):
Likewise.
* include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve):
Adjust.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve):
Likewise.

From-SVN: r108034

libstdc++-v3/ChangeLog
libstdc++-v3/include/ext/rc_string_base.h
libstdc++-v3/include/ext/sso_string_base.h
libstdc++-v3/include/ext/vstring.h
libstdc++-v3/include/ext/vstring.tcc

index de206f6ef44a08f7d04064f695efc9d0f2be0870..3dcd4d8544051686afd42707b13a430e8f57200d 100644 (file)
@@ -1,3 +1,88 @@
+2005-12-04  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/ext/vstring.h (__versa_string<>::operator+, all
+       versions): Move out of line...
+       * include/ext/vstring.tcc (__versa_string<>::operator+): ...
+       here; consistently use reserve for the benefit of sso_string_base;
+       prefer push_back to single-char append when appropriate.
+
+       * include/ext/vstring.h (__versa_string<>::push_back): Don't
+       call _M_reserve, _M_mutate instead.
+       (reserve): Just forward to _M_reserve.
+       * include/ext/vstring.tcc (__versa_string<>::_M_reserve): Remove.
+       * include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve): Also
+       do the initial checks (first on length, in case __res == capacity).
+       * include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve:
+       Likewise; don't call _M_set_length unnecessarily.
+
+2005-12-04  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/ext/vstring.h (__versa_string<>::_M_append): New.
+       (append(const __versa_string&), append(const __versa_string&,
+       size_type, size_type), append(const _CharT*, size_type),
+       append(const _CharT*)): Use it.
+       (append(size_type, _CharT)): Delegate to _M_replace_aux.
+       (assign(const __versa_string&, size_type, size_type),
+       assign(const _CharT*), replace(size_type, size_type,
+       const _CharT*, size_type)): Forward to _M_replace.
+       * include/ext/vstring.tcc (__versa_string<>::_M_append):
+       Define, core append functionality.
+       (_M_replace): Simplify, move __s == 0 case to _M_replace_aux.
+       (_M_replace_aux): Reorganize, don't call _M_replace.
+
+2005-12-04  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/ext/vstring.tcc (__versa_string<>::_M_replace):
+       Perform _M_check_length at the beginning and remove it from ...
+       (replace, _M_replace_dispatch, _M_replace_aux, assign): ... here.
+       (assign): Now move inline.
+       (resize): Don't call _M_check_length redundantly, append does.
+
+2005-12-04  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/ext/sso_string_base.h (__sso_string_base<>::_M_get_allocator):
+       Add non const version.
+       * include/ext/rc_string_base.h (__rc_string_base<>::_M_get_allocator):
+       Likewise.
+       
+       * include/ext/sso_string_base.h (__sso_string_base<>::_M_erase): Add.
+       * include/ext/rc_string_base.h (__rc_string_base<>::_M_erase): Likewise.
+       (_M_leak_hard): Use it.
+       * include/ext/vstring.h (__versa_string<>::clear, erase, all
+       versions): Use it.
+       * include/ext/vstring.tcc (__versa_string<>::resize): Likewise.
+
+       * include/ext/vstring.h (__versa_string<>::_M_replace_safe):
+       Remove.
+       * include/ext/vstring.h (__versa_string<>::_M_replace): New, does
+       the in-place work or delegates to _M_mutate in case of reallocation.
+       * include/ext/vstring.tcc (__versa_string<>::_M_replace_safe):
+       Remove.
+       * include/ext/vstring.tcc (__versa_string<>::_M_replace): Define.
+       (assign, replace, _M_replace_dispatch, _M_replace_aux): Use it.
+       * include/ext/sso_string_base.h (__sso_string_base<>::_M_mutate):
+       Change to manage only reallocations.
+       * include/ext/rc_string_base.h (__rc_string_base<>::_M_mutate):
+       Likewise.
+
+       * include/ext/vstring.h (__versa_string<>::insert(size_type,
+       const __versa_string&), insert(size_type, const __versa_string&,
+       size_type, size_type), insert(size_type, const _CharT*, size_type),
+       insert(size_type, const _CharT*)): Delegate to replace.
+
+       * include/ext/vstring.h (__versa_string<>::reserve): Move out of
+       line.
+       * include/ext/vstring.tcc (__versa_string<>::reserve): Do the
+       checks and call _M_reserve.
+       * include/ext/vstring.h (__versa_string<>::append): Call _M_reserve
+       instead of reserve.
+       * include/ext/vstring.tcc (__versa_string<>::append, all versions):
+       Likewise.
+       * include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve):
+       Adjust.
+       * include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve):
+       Likewise.
+
 2005-12-02  David Billinghurst (David.Billinghurst@riotinto.com)
 
        PR testsuite/25193
index 8fb7531eadd14fceded8a562bea2642a8fd129d9..9636a813a02fde8adc7a574dc58d9a0b3eceb156 100644 (file)
@@ -311,6 +311,10 @@ namespace __gnu_cxx
       ~__rc_string_base()
       { _M_dispose(); }      
 
+      allocator_type&
+      _M_get_allocator()
+      { return _M_dataplus; }
+
       const allocator_type&
       _M_get_allocator() const
       { return _M_dataplus; }
@@ -325,7 +329,11 @@ namespace __gnu_cxx
       _M_reserve(size_type __res);
 
       void
-      _M_mutate(size_type __pos, size_type __len1, size_type __len2);
+      _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
+               size_type __len2);
+      
+      void
+      _M_erase(size_type __pos, size_type __n);
     };
 
   template<typename _CharT, typename _Traits, typename _Alloc>
@@ -377,8 +385,8 @@ namespace __gnu_cxx
 
       // NB: Need an array of char_type[__capacity], plus a terminating
       // null char_type() element, plus enough for the _Rep data structure,
-      // plus sizeof(size_type) - 1 to upper round to a size multiple
-      // of sizeof(size_type).
+      // plus sizeof(_Rep) - 1 to upper round to a size multiple of
+      // sizeof(_Rep).
       // Whew. Seemingly so needy, yet so elemental.
       size_type __size = ((__capacity + 1) * sizeof(_CharT)
                          + 2 * sizeof(_Rep) - 1);
@@ -458,7 +466,7 @@ namespace __gnu_cxx
     _M_leak_hard()
     {
       if (_M_is_shared())
-       _M_mutate(0, 0, 0);
+       _M_erase(0, 0);
       _M_set_leaked();
     }
 
@@ -490,7 +498,7 @@ namespace __gnu_cxx
          {
            while (__beg != __end)
              {
-               if (__len == __r->_M_capacity)
+               if (__len == __r->_M_info._M_capacity)
                  {
                    // Allocate more space.
                    _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
@@ -594,12 +602,12 @@ namespace __gnu_cxx
     __rc_string_base<_CharT, _Traits, _Alloc>::
     _M_reserve(size_type __res)
     {
+      // Make sure we don't shrink below the current size.
+      if (__res < _M_length())
+       __res = _M_length();
+      
       if (__res != _M_capacity() || _M_is_shared())
        {
-         // Make sure we don't shrink below the current size.
-         if (__res < _M_length())
-           __res = _M_length();
-         
          _CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(),
                                             __res - _M_length());
          _M_dispose();
@@ -610,13 +618,35 @@ namespace __gnu_cxx
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     __rc_string_base<_CharT, _Traits, _Alloc>::
-    _M_mutate(size_type __pos, size_type __len1, size_type __len2)
+    _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
+             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;
+      const size_type __how_much = _M_length() - __pos - __len1;
+      
+      _Rep* __r = _Rep::_S_create(_M_length() + __len2 - __len1,
+                                 _M_capacity(), _M_get_allocator());
       
-      if (__new_size > _M_capacity() || _M_is_shared())
+      if (__pos)
+       _S_copy(__r->_M_refdata(), _M_data(), __pos);
+      if (__s && __len2)
+       _S_copy(__r->_M_refdata() + __pos, __s, __len2);
+      if (__how_much)
+       _S_copy(__r->_M_refdata() + __pos + __len2,
+               _M_data() + __pos + __len1, __how_much);
+      
+      _M_dispose();
+      _M_data(__r->_M_refdata());
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __rc_string_base<_CharT, _Traits, _Alloc>::
+    _M_erase(size_type __pos, size_type __n)
+    {
+      const size_type __new_size = _M_length() - __n;
+      const size_type __how_much = _M_length() - __pos - __n;
+      
+      if (_M_is_shared())
        {
          // Must reallocate.
          _Rep* __r = _Rep::_S_create(__new_size, _M_capacity(),
@@ -625,19 +655,20 @@ namespace __gnu_cxx
          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);
+           _S_copy(__r->_M_refdata() + __pos,
+                   _M_data() + __pos + __n, __how_much);
 
          _M_dispose();
          _M_data(__r->_M_refdata());
        }
-      else if (__how_much && __len1 != __len2)
+      else if (__how_much && __n)
        {
          // Work in-place.
-         _S_move(_M_data() + __pos + __len2,
-                 _M_data() + __pos + __len1, __how_much);
+         _S_move(_M_data() + __pos,
+                 _M_data() + __pos + __n, __how_much);
        }
-      _M_rep()->_M_set_length(__new_size);
+
+      _M_rep()->_M_set_length(__new_size);      
     }
 } // namespace __gnu_cxx
 
index f4bd3fb1eeca888b4cca01573896ecff6099e62a..e552a57c5e3479a08653aa6d31462ecc9b0ab3bb 100644 (file)
@@ -202,6 +202,10 @@ namespace __gnu_cxx
       ~__sso_string_base()
       { _M_dispose(); }
 
+      allocator_type&
+      _M_get_allocator()
+      { return _M_dataplus; }
+
       const allocator_type&
       _M_get_allocator() const
       { return _M_dataplus; }
@@ -216,7 +220,11 @@ namespace __gnu_cxx
       _M_reserve(size_type __res);
 
       void
-      _M_mutate(size_type __pos, size_type __len1, size_type __len2);
+      _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
+               size_type __len2);
+
+      void
+      _M_erase(size_type __pos, size_type __n);
     };
 
   template<typename _CharT, typename _Traits, typename _Alloc>
@@ -471,19 +479,18 @@ namespace __gnu_cxx
     __sso_string_base<_CharT, _Traits, _Alloc>::
     _M_reserve(size_type __res)
     {
+      // Make sure we don't shrink below the current size.
+      if (__res < _M_length())
+       __res = _M_length();
+
       const size_type __capacity = _M_capacity();
       if (__res != __capacity)
        {
-         // Make sure we don't shrink below the current size.
-         if (__res < _M_length())
-           __res = _M_length();
-
          if (__res > __capacity
              || __res > size_type(_S_local_capacity))
            {
              _CharT* __tmp = _M_create(__res, __capacity);
-             if (_M_length())
-               _S_copy(__tmp, _M_data(), _M_length());
+             _S_copy(__tmp, _M_data(), _M_length() + 1);
              _M_dispose();
              _M_data(__tmp);
              _M_capacity(__res);
@@ -491,49 +498,49 @@ namespace __gnu_cxx
          else if (!_M_is_local())
            {
              const size_type __tmp_capacity = _M_allocated_capacity;
-             if (_M_length())
-               _S_copy(_M_local_data, _M_data(), _M_length());
+             _S_copy(_M_local_data, _M_data(), _M_length() + 1);
              _M_destroy(__tmp_capacity + 1);
              _M_data(_M_local_data);
-           }     
-         
-         _M_set_length(_M_length());
+           }
        }
     }
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     void
     __sso_string_base<_CharT, _Traits, _Alloc>::
-    _M_mutate(size_type __pos, size_type __len1, size_type __len2)
+    _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
+             const 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;
+      const size_type __how_much = _M_length() - __pos - __len1;
       
-      if (__new_size > _M_capacity())
-       {
-         // Must reallocate.
-         size_type __new_capacity = __new_size;
-         _CharT* __r = _M_create(__new_capacity, _M_capacity());
+      size_type __new_capacity = _M_length() + __len2 - __len1;
+      _CharT* __r = _M_create(__new_capacity, _M_capacity());
+
+      if (__pos)
+       _S_copy(__r, _M_data(), __pos);
+      if (__s && __len2)
+       _S_copy(__r + __pos, __s, __len2);
+      if (__how_much)
+       _S_copy(__r + __pos + __len2,
+               _M_data() + __pos + __len1, __how_much);
+      
+      _M_dispose();
+      _M_data(__r);
+      _M_capacity(__new_capacity);
+    }
 
-         if (__pos)
-           _S_copy(__r, _M_data(), __pos);
-         if (__how_much)
-           _S_copy(__r + __pos + __len2,
-                   _M_data() + __pos + __len1, __how_much);
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    void
+    __sso_string_base<_CharT, _Traits, _Alloc>::
+    _M_erase(size_type __pos, size_type __n)
+    {
+      const size_type __how_much = _M_length() - __pos - __n;
 
-         _M_dispose();
-         _M_data(__r);
-         _M_capacity(__new_capacity);
-       }
-      else if (__how_much && __len1 != __len2)
-       {
-         // Work in-place.
-         _S_move(_M_data() + __pos + __len2,
-                 _M_data() + __pos + __len1, __how_much);
-       }
+      if (__how_much && __n)
+       _S_move(_M_data() + __pos, _M_data() + __pos + __n,
+               __how_much);
 
-      _M_set_length(__new_size);
+      _M_set_length(_M_length() - __n);
     }
 } // namespace __gnu_cxx
 
index 1aaa87665e7984cb9b28b3fda66a46e4c0691629..4a5228518d7e61769d86b0a61c3c90d771d9cb5f 100644 (file)
@@ -402,14 +402,14 @@ namespace __gnu_cxx
        */
       void
       reserve(size_type __res_arg = 0)
-      {        this->_M_reserve(__res_arg); }
+      { this->_M_reserve(__res_arg); }
 
       /**
        *  Erases the string, making it empty.
        */
       void
       clear()
-      { this->_M_mutate(0, this->size(), 0); }
+      { this->_M_erase(size_type(0), this->size()); }
 
       /**
        *  Returns true if the %string is empty.  Equivalent to *this == "".
@@ -529,7 +529,8 @@ namespace __gnu_cxx
        *  @return  Reference to this string.
        */
       __versa_string&
-      append(const __versa_string& __str);
+      append(const __versa_string& __str)
+      { return _M_append(__str._M_data(), __str.size()); }
 
       /**
        *  @brief  Append a substring.
@@ -544,7 +545,10 @@ namespace __gnu_cxx
        *  characters in @a str, the remainder of @a str is appended.
        */
       __versa_string&
-      append(const __versa_string& __str, size_type __pos, size_type __n);
+      append(const __versa_string& __str, size_type __pos, size_type __n)
+      { return _M_append(__str._M_data()
+                        + __str._M_check(__pos, "__versa_string::append"),
+                        __str._M_limit(__pos, __n)); }
 
       /**
        *  @brief  Append a C substring.
@@ -553,7 +557,12 @@ namespace __gnu_cxx
        *  @return  Reference to this string.
        */
       __versa_string&
-      append(const _CharT* __s, size_type __n);
+      append(const _CharT* __s, size_type __n)
+      {
+       __glibcxx_requires_string_len(__s, __n);
+       _M_check_length(size_type(0), __n, "__versa_string::append");
+       return _M_append(__s, __n);
+      }
 
       /**
        *  @brief  Append a C string.
@@ -564,7 +573,9 @@ namespace __gnu_cxx
       append(const _CharT* __s)
       {
        __glibcxx_requires_string(__s);
-       return this->append(__s, traits_type::length(__s));
+       const size_type __n = traits_type::length(__s);
+       _M_check_length(size_type(0), __n, "__versa_string::append");
+       return _M_append(__s, __n);
       }
 
       /**
@@ -576,7 +587,8 @@ namespace __gnu_cxx
        *  Appends n copies of c to this string.
        */
       __versa_string&
-      append(size_type __n, _CharT __c);
+      append(size_type __n, _CharT __c)
+      { return _M_replace_aux(this->size(), size_type(0), __n, __c); }
 
       /**
        *  @brief  Append a range of characters.
@@ -598,11 +610,11 @@ namespace __gnu_cxx
       void
       push_back(_CharT __c)
       { 
-       const size_type __len = 1 + this->size();
-       if (__len > this->capacity() || this->_M_is_shared())
-         this->reserve(__len);
-       traits_type::assign(this->_M_data()[this->size()], __c);
-       this->_M_set_length(__len);
+       const size_type __size = this->size();
+       if (__size + 1 > this->capacity() || this->_M_is_shared())
+         this->_M_mutate(__size, size_type(0), 0, size_type(1));
+       traits_type::assign(this->_M_data()[__size], __c);
+       this->_M_set_length(__size + 1);
       }
 
       /**
@@ -631,9 +643,9 @@ namespace __gnu_cxx
        */
       __versa_string&
       assign(const __versa_string& __str, size_type __pos, size_type __n)
-      { return this->assign(__str._M_data()
-                           + __str._M_check(__pos, "__versa_string::assign"),
-                           __str._M_limit(__pos, __n)); }
+      { return _M_replace(size_type(0), this->size(), __str._M_data()
+                         + __str._M_check(__pos, "__versa_string::assign"),
+                         __str._M_limit(__pos, __n)); }
 
       /**
        *  @brief  Set value to a C substring.
@@ -646,7 +658,11 @@ namespace __gnu_cxx
        *  available characters in @a s, the remainder of @a s is used.
        */
       __versa_string&
-      assign(const _CharT* __s, size_type __n);
+      assign(const _CharT* __s, size_type __n)
+      {
+       __glibcxx_requires_string_len(__s, __n);
+       return _M_replace(size_type(0), this->size(), __s, __n);
+      }
 
       /**
        *  @brief  Set value to contents of a C string.
@@ -661,7 +677,8 @@ namespace __gnu_cxx
       assign(const _CharT* __s)
       {
        __glibcxx_requires_string(__s);
-       return this->assign(__s, traits_type::length(__s));
+       return _M_replace(size_type(0), this->size(), __s,
+                         traits_type::length(__s));
       }
 
       /**
@@ -735,7 +752,8 @@ namespace __gnu_cxx
       */
       __versa_string&
       insert(size_type __pos1, const __versa_string& __str)
-      { return this->insert(__pos1, __str, size_type(0), __str.size()); }
+      { return this->replace(__pos1, size_type(0),
+                            __str._M_data(), __str.size()); }
 
       /**
        *  @brief  Insert a substring.
@@ -758,9 +776,9 @@ namespace __gnu_cxx
       __versa_string&
       insert(size_type __pos1, const __versa_string& __str,
             size_type __pos2, size_type __n)
-      { return this->insert(__pos1, __str._M_data()
-                           + __str._M_check(__pos2, "__versa_string::insert"),
-                           __str._M_limit(__pos2, __n)); }
+      { return this->replace(__pos1, size_type(0), __str._M_data()
+                            + __str._M_check(__pos2, "__versa_string::insert"),
+                            __str._M_limit(__pos2, __n)); }
 
       /**
        *  @brief  Insert a C substring.
@@ -779,7 +797,8 @@ namespace __gnu_cxx
        *  thrown.
       */
       __versa_string&
-      insert(size_type __pos, const _CharT* __s, size_type __n);
+      insert(size_type __pos, const _CharT* __s, size_type __n)
+      { return this->replace(__pos, size_type(0), __s, __n); }
 
       /**
        *  @brief  Insert a C string.
@@ -800,7 +819,8 @@ namespace __gnu_cxx
       insert(size_type __pos, const _CharT* __s)
       {
        __glibcxx_requires_string(__s);
-       return this->insert(__pos, __s, traits_type::length(__s));
+       return this->replace(__pos, size_type(0), __s,
+                            traits_type::length(__s));
       }
 
       /**
@@ -843,7 +863,7 @@ namespace __gnu_cxx
        const size_type __pos = __p - _M_ibegin();
        _M_replace_aux(__pos, size_type(0), size_type(1), __c);
        this->_M_set_leaked();
-       return _M_ibegin() + __pos;
+       return iterator(this->_M_data() + __pos);
       }
 
       /**
@@ -863,8 +883,8 @@ namespace __gnu_cxx
       __versa_string&
       erase(size_type __pos = 0, size_type __n = npos)
       { 
-       this->_M_mutate(_M_check(__pos, "__versa_string::erase"),
-                       _M_limit(__pos, __n), size_type(0));
+       this->_M_erase(_M_check(__pos, "__versa_string::erase"),
+                      _M_limit(__pos, __n));
        return *this;
       }
 
@@ -882,9 +902,9 @@ namespace __gnu_cxx
        _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
                                 && __position < _M_iend());
        const size_type __pos = __position - _M_ibegin();
-       this->_M_mutate(__pos, size_type(1), size_type(0));
+       this->_M_erase(__pos, size_type(1));
        this->_M_set_leaked();
-       return _M_ibegin() + __pos;
+       return iterator(this->_M_data() + __pos);
       }
 
       /**
@@ -902,9 +922,9 @@ namespace __gnu_cxx
        _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
                                 && __last <= _M_iend());
         const size_type __pos = __first - _M_ibegin();
-       this->_M_mutate(__pos, __last - __first, size_type(0));
+       this->_M_erase(__pos, __last - __first);
        this->_M_set_leaked();
-       return _M_ibegin() + __pos;
+       return iterator(this->_M_data() + __pos);
       }
 
       /**
@@ -974,7 +994,12 @@ namespace __gnu_cxx
       */
       __versa_string&
       replace(size_type __pos, size_type __n1, const _CharT* __s,
-             size_type __n2);
+             size_type __n2)
+      {
+       __glibcxx_requires_string_len(__s, __n2);
+       return _M_replace(_M_check(__pos, "__versa_string::replace"),
+                         _M_limit(__pos, __n1), __s, __n2);
+      }
 
       /**
        *  @brief  Replace characters with value of a C string.
@@ -1187,8 +1212,11 @@ namespace __gnu_cxx
                     _CharT __c);
 
       __versa_string&
-      _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
-                     size_type __n2);
+      _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
+                const size_type __len2);
+
+      __versa_string&
+      _M_append(const _CharT* __s, size_type __n);
 
     public:
 
@@ -1771,12 +1799,7 @@ namespace __gnu_cxx
           template <typename, typename, typename> class _Base>
     __versa_string<_CharT, _Traits, _Alloc, _Base>
     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
-             const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
-    {
-      __versa_string<_CharT, _Traits, _Alloc, _Base> __str(__lhs);
-      __str.append(__rhs);
-      return __str;
-    }
+             const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs);
 
   /**
    *  @brief  Concatenate C string and string.
@@ -1810,14 +1833,9 @@ namespace __gnu_cxx
    */
   template<typename _CharT, typename _Traits, typename _Alloc,
           template <typename, typename, typename> class _Base>
-    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
-             const _CharT* __rhs)
-    {
-      __versa_string<_CharT, _Traits, _Alloc, _Base> __str(__lhs);
-      __str.append(__rhs);
-      return __str;
-    }
+             const _CharT* __rhs);
 
   /**
    *  @brief  Concatenate string and character.
@@ -1827,17 +1845,9 @@ namespace __gnu_cxx
    */
   template<typename _CharT, typename _Traits, typename _Alloc,
           template <typename, typename, typename> class _Base>
-    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
     operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
-             _CharT __rhs)
-    {
-      typedef __versa_string<_CharT, _Traits, _Alloc, _Base>
-                                                       __string_type;
-      typedef typename __string_type::size_type                __size_type;
-      __string_type __str(__lhs);
-      __str.append(__size_type(1), __rhs);
-      return __str;
-    }
+             _CharT __rhs);
 
   // operator ==
   /**
index 76fa96bcbd3427800db45ffaeae65125390e2145..2fed7e2e14dc26fc2d588cc17348ff74b2629d42 100644 (file)
@@ -47,192 +47,37 @@ namespace __gnu_cxx
 
   template<typename _CharT, typename _Traits, typename _Alloc,
           template <typename, typename, typename> class _Base>
-    __versa_string<_CharT, _Traits, _Alloc, _Base>&
-    __versa_string<_CharT, _Traits, _Alloc, _Base>::
-    assign(const _CharT* __s, size_type __n)
-    {
-      __glibcxx_requires_string_len(__s, __n);
-      _M_check_length(this->size(), __n, "__versa_string::assign");
-      if (_M_disjunct(__s) || this->_M_is_shared())
-       return _M_replace_safe(size_type(0), this->size(), __s, __n);
-      else
-       {
-         // Work in-place.
-         const size_type __pos = __s - this->_M_data();
-         if (__pos >= __n)
-           this->_S_copy(this->_M_data(), __s, __n);
-         else if (__pos)
-           this->_S_move(this->_M_data(), __s, __n);
-         this->_M_set_length(__n);
-         return *this;
-       }
-     }
-
-  template<typename _CharT, typename _Traits, typename _Alloc,
-          template <typename, typename, typename> class _Base>
-    __versa_string<_CharT, _Traits, _Alloc, _Base>&
+    void
     __versa_string<_CharT, _Traits, _Alloc, _Base>::
-    append(size_type __n, _CharT __c)
+    resize(size_type __n, _CharT __c)
     {
-      if (__n)
-       {
-         _M_check_length(size_type(0), __n, "__versa_string::append");   
-         const size_type __len = __n + this->size();
-         if (__len > this->capacity() || this->_M_is_shared())
-           this->reserve(__len);
-         this->_S_assign(this->_M_data() + this->size(), __n, __c);
-         this->_M_set_length(__len);
-       }
-      return *this;
+      const size_type __size = this->size();
+      if (__size < __n)
+       this->append(__n - __size, __c);
+      else if (__n < __size)
+       this->_M_erase(__n, __size - __n);
     }
 
   template<typename _CharT, typename _Traits, typename _Alloc,
           template <typename, typename, typename> class _Base>
     __versa_string<_CharT, _Traits, _Alloc, _Base>&
     __versa_string<_CharT, _Traits, _Alloc, _Base>::
-    append(const _CharT* __s, size_type __n)
+    _M_append(const _CharT* __s, size_type __n)
     {
-      __glibcxx_requires_string_len(__s, __n);
-      if (__n)
-       {
-         _M_check_length(size_type(0), __n, "__versa_string::append");
-         const size_type __len = __n + this->size();
-         if (__len > this->capacity() || this->_M_is_shared())
-           {
-             if (_M_disjunct(__s))
-               this->reserve(__len);
-             else
-               {
-                 const size_type __off = __s - this->_M_data();
-                 this->reserve(__len);
-                 __s = this->_M_data() + __off;
-               }
-           }
-         this->_S_copy(this->_M_data() + this->size(), __s, __n);
-         this->_M_set_length(__len);
-       }
-      return *this;
-    }
+      const size_type __len = __n + this->size();
 
-  template<typename _CharT, typename _Traits, typename _Alloc,
-          template <typename, typename, typename> class _Base>
-    __versa_string<_CharT, _Traits, _Alloc, _Base>&
-    __versa_string<_CharT, _Traits, _Alloc, _Base>::
-    append(const __versa_string& __str)
-    {
-      const size_type __size = __str.size();
-      if (__size)
+      if (__len <= this->capacity() && !this->_M_is_shared())
        {
-         const size_type __len = __size + this->size();
-         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_set_length(__len);
+         if (__n)
+           this->_S_copy(this->_M_data() + this->size(), __s, __n);
        }
-      return *this;
-    }    
+      else
+       this->_M_mutate(this->size(), size_type(0), __s, __n);
 
-  template<typename _CharT, typename _Traits, typename _Alloc,
-          template <typename, typename, typename> class _Base>
-    __versa_string<_CharT, _Traits, _Alloc, _Base>&
-    __versa_string<_CharT, _Traits, _Alloc, _Base>::
-    append(const __versa_string& __str, size_type __pos, size_type __n)
-    {
-      __str._M_check(__pos, "__versa_string::append");
-      __n = __str._M_limit(__pos, __n);
-      if (__n)
-       {
-         const size_type __len = __n + this->size();
-         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_set_length(__len);     
-       }
+      this->_M_set_length(__len);
       return *this;
     }
 
-   template<typename _CharT, typename _Traits, typename _Alloc,
-           template <typename, typename, typename> class _Base>
-     __versa_string<_CharT, _Traits, _Alloc, _Base>&
-     __versa_string<_CharT, _Traits, _Alloc, _Base>::
-     insert(size_type __pos, const _CharT* __s, size_type __n)
-     {
-       __glibcxx_requires_string_len(__s, __n);
-       _M_check(__pos, "__versa_string::insert");
-       _M_check_length(size_type(0), __n, "__versa_string::insert");
-       if (_M_disjunct(__s) || this->_M_is_shared())
-         return _M_replace_safe(__pos, size_type(0), __s, __n);
-       else
-         {
-           // Work in-place.
-           const size_type __off = __s - this->_M_data();
-           this->_M_mutate(__pos, 0, __n);
-           __s = this->_M_data() + __off;
-           _CharT* __p = this->_M_data() + __pos;
-           if (__s  + __n <= __p)
-             this->_S_copy(__p, __s, __n);
-           else if (__s >= __p)
-             this->_S_copy(__p, __s + __n, __n);
-           else
-             {
-              const size_type __nleft = __p - __s;
-               this->_S_copy(__p, __s, __nleft);
-               this->_S_copy(__p + __nleft, __p + __n, __n - __nleft);
-             }
-           return *this;
-         }
-     }
-
-   template<typename _CharT, typename _Traits, typename _Alloc,
-           template <typename, typename, typename> class _Base>
-     __versa_string<_CharT, _Traits, _Alloc, _Base>&
-     __versa_string<_CharT, _Traits, _Alloc, _Base>::
-     replace(size_type __pos, size_type __n1, const _CharT* __s,
-            size_type __n2)
-     {
-       __glibcxx_requires_string_len(__s, __n2);
-       _M_check(__pos, "__versa_string::replace");
-       __n1 = _M_limit(__pos, __n1);
-       _M_check_length(__n1, __n2, "__versa_string::replace");
-       bool __left;
-       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)
-        {
-          // Work in-place: non-overlapping case.
-          size_type __off = __s - this->_M_data();
-          __left ? __off : (__off += __n2 - __n1);
-          this->_M_mutate(__pos, __n1, __n2);
-          this->_S_copy(this->_M_data() + __pos,
-                        this->_M_data() + __off, __n2);
-          return *this;
-        }
-       else
-        {
-          // Todo: overlapping case.
-          const __versa_string __tmp(__s, __n2);
-          return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
-        }
-     }
-
-  template<typename _CharT, typename _Traits, typename _Alloc,
-          template <typename, typename, typename> class _Base>
-    void
-    __versa_string<_CharT, _Traits, _Alloc, _Base>::
-    resize(size_type __n, _CharT __c)
-    {
-      const size_type __size = this->size();
-      _M_check_length(__size, __n, "__versa_string::resize");
-      if (__size < __n)
-       this->append(__n - __size, __c);
-      else if (__n < __size)
-       this->erase(__n);
-      // else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
-    }
-
   template<typename _CharT, typename _Traits, typename _Alloc,
           template <typename, typename, typename> class _Base>
     template<typename _InputIterator>
@@ -243,10 +88,8 @@ namespace __gnu_cxx
       {
        const __versa_string __s(__k1, __k2);
        const size_type __n1 = __i2 - __i1;
-       _M_check_length(__n1, __s.size(),
-                       "__versa_string::_M_replace_dispatch");
-       return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
-                              __s.size());
+       return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
+                         __s.size());
       }
 
   template<typename _CharT, typename _Traits, typename _Alloc,
@@ -257,9 +100,25 @@ namespace __gnu_cxx
                   _CharT __c)
     {
       _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
-      this->_M_mutate(__pos1, __n1, __n2);
+
+      const size_type __old_size = this->size();
+      const size_type __new_size = __old_size + __n2 - __n1;
+
+      if (__new_size <= this->capacity() && !this->_M_is_shared())
+       {
+         _CharT* __p = this->_M_data() + __pos1;
+
+         const size_type __how_much = __old_size - __pos1 - __n1;
+         if (__how_much && __n1 != __n2)
+           this->_S_move(__p + __n2, __p + __n1, __how_much);
+       }
+      else
+       this->_M_mutate(__pos1, __n1, 0, __n2);
+
       if (__n2)
        this->_S_assign(this->_M_data() + __pos1, __n2, __c);
+
+      this->_M_set_length(__new_size);
       return *this;
     }
 
@@ -267,23 +126,77 @@ namespace __gnu_cxx
           template <typename, typename, typename> class _Base>
     __versa_string<_CharT, _Traits, _Alloc, _Base>&
     __versa_string<_CharT, _Traits, _Alloc, _Base>::
-    _M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s,
-                   size_type __n2)
+    _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
+              const size_type __len2)
     {
-      this->_M_mutate(__pos1, __n1, __n2);
-      if (__n2)
-       this->_S_copy(this->_M_data() + __pos1, __s, __n2);
+      _M_check_length(__len1, __len2, "__versa_string::_M_replace");
+
+      const size_type __old_size = this->size();
+      const size_type __new_size = __old_size + __len2 - __len1;
+      
+      if (__new_size <= this->capacity() && !this->_M_is_shared())
+       {
+         _CharT* __p = this->_M_data() + __pos;
+
+         const size_type __how_much = __old_size - __pos - __len1;
+         if (_M_disjunct(__s))
+           {
+             if (__how_much && __len1 != __len2)
+               this->_S_move(__p + __len2, __p + __len1, __how_much);
+             if (__len2)
+               this->_S_copy(__p, __s, __len2);
+           }
+         else
+           {
+             // Work in-place.
+             if (__len2 && __len2 <= __len1)
+               this->_S_move(__p, __s, __len2);
+             if (__how_much && __len1 != __len2)
+               this->_S_move(__p + __len2, __p + __len1, __how_much);
+             if (__len2 > __len1)
+               {
+                 if (__s + __len2 <= __p + __len1)
+                   this->_S_move(__p, __s, __len2);
+                 else if (__s >= __p + __len1)
+                   this->_S_copy(__p, __s + __len2 - __len1, __len2);
+                 else
+                   {
+                     const size_type __nleft = (__p + __len1) - __s;
+                     this->_S_move(__p, __s, __nleft);
+                     this->_S_copy(__p + __nleft, __p + __len2,
+                                   __len2 - __nleft);
+                   }
+               }
+           }
+       }
+      else
+       this->_M_mutate(__pos, __len1, __s, __len2);
+
+      this->_M_set_length(__new_size);
       return *this;
     }
-   
+  
+  template<typename _CharT, typename _Traits, typename _Alloc,
+          template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+             const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
+    {
+      __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
+      __str.reserve(__lhs.size() + __rhs.size());
+      __str.append(__lhs);
+      __str.append(__rhs);
+      return __str;
+    }
+
   template<typename _CharT, typename _Traits, typename _Alloc,
           template <typename, typename, typename> class _Base>
     __versa_string<_CharT, _Traits, _Alloc, _Base>
     operator+(const _CharT* __lhs,
-             const __versa_string<_CharT, _Traits, _Alloc>& __rhs)
+             const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
     {
       __glibcxx_requires_string(__lhs);
-      typedef __versa_string<_CharT, _Traits, _Alloc> __string_type;
+      typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
       typedef typename __string_type::size_type          __size_type;
       const __size_type __len = _Traits::length(__lhs);
       __string_type __str;
@@ -299,13 +212,40 @@ namespace __gnu_cxx
     operator+(_CharT __lhs,
              const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
     {
-      typedef __versa_string<_CharT, _Traits, _Alloc> __string_type;
+      __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
+      __str.reserve(__rhs.size() + 1);
+      __str.push_back(__lhs);
+      __str.append(__rhs);
+      return __str;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+          template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+             const _CharT* __rhs)
+    {
+      __glibcxx_requires_string(__rhs);
+      typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
       typedef typename __string_type::size_type          __size_type;
+      const __size_type __len = _Traits::length(__rhs);
       __string_type __str;
-      const __size_type __len = __rhs.size();
-      __str.reserve(__len + 1);
-      __str.append(__size_type(1), __lhs);
-      __str.append(__rhs);
+      __str.reserve(__lhs.size() + __len);
+      __str.append(__lhs);
+      __str.append(__rhs, __len);
+      return __str;
+    }
+
+  template<typename _CharT, typename _Traits, typename _Alloc,
+          template <typename, typename, typename> class _Base>
+    __versa_string<_CharT, _Traits, _Alloc, _Base>
+    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
+             _CharT __rhs)
+    {
+      __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
+      __str.reserve(__lhs.size() + 1);
+      __str.append(__lhs);
+      __str.push_back(__rhs);
       return __str;
     }