This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[v3] string assign/replace fixes



This is related to the sept libstdc++ outstanding email

tested x86/linux

2001-10-30  Paolo Carlini  <pcarlini@unitus.it>
	    Benjamin Kosnik  <bkoz@redhat.com>

	* include/bits/basic_string.h: Tweaks.
	* include/bits/basic_string.tcc (string::_M_replace(iterator,
	iterator, _ForwardIter, _ForwardIter, forward_iterator_tag): Fix.
	* src/string-inst.cc: Tweaks, add instantiation.
	* testsuite/21_strings/replace.cc (test02): Add test.
	* testsuite/21_strings/assign.cc (test01): New file.
	
Index: include/bits/basic_string.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/basic_string.h,v
retrieving revision 1.9
diff -c -p -r1.9 basic_string.h
*** basic_string.h	2001/07/20 00:09:31	1.9
--- basic_string.h	2001/10/31 08:23:43
***************
*** 40,46 ****
  
  namespace std
  {
- 
    // Documentation?  What's that? 
    // Nathan Myers <ncm@cantrip.org>.
    //
--- 40,45 ----
*************** namespace std
*** 284,290 ****
          _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
          { 
  	  for (; __k1 != __k2; ++__k1, ++__p) 
! 	    traits_type::assign(*__p, *__k1); //these types are off
  	}
  
        static void
--- 283,289 ----
          _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2)
          { 
  	  for (; __k1 != __k2; ++__k1, ++__p) 
! 	    traits_type::assign(*__p, *__k1); // These types are off.
  	}
  
        static void
*************** namespace std
*** 337,343 ****
        basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
  
        template<class _InputIterator>
!         basic_string(_InputIterator __begin, _InputIterator __end,
  		     const _Alloc& __a = _Alloc());
  
        ~basic_string() 
--- 336,342 ----
        basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
  
        template<class _InputIterator>
!         basic_string(_InputIterator __beg, _InputIterator __end,
  		     const _Alloc& __a = _Alloc());
  
        ~basic_string() 
Index: include/bits/basic_string.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/basic_string.tcc,v
retrieving revision 1.7
diff -c -p -r1.7 basic_string.tcc
*** basic_string.tcc	2001/10/19 18:38:59	1.7
--- basic_string.tcc	2001/10/31 08:23:44
*************** namespace std
*** 130,136 ****
    template<typename _CharT, typename _Traits, typename _Alloc>
      template <class _InIter>
        _CharT*
!       basic_string<_CharT,_Traits,_Alloc>::
        _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, 
  		   forward_iterator_tag)
        {
--- 130,136 ----
    template<typename _CharT, typename _Traits, typename _Alloc>
      template <class _InIter>
        _CharT*
!       basic_string<_CharT, _Traits, _Alloc>::
        _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, 
  		   forward_iterator_tag)
        {
*************** namespace std
*** 156,162 ****
  
    template<typename _CharT, typename _Traits, typename _Alloc>
      _CharT*
!     basic_string<_CharT,_Traits, _Alloc>::
      _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
      {
        if (__n == 0 && __a == _Alloc())
--- 156,162 ----
  
    template<typename _CharT, typename _Traits, typename _Alloc>
      _CharT*
!     basic_string<_CharT, _Traits, _Alloc>::
      _S_construct(size_type __n, _CharT __c, const _Alloc& __a)
      {
        if (__n == 0 && __a == _Alloc())
*************** namespace std
*** 446,463 ****
        _M_replace(iterator __i1, iterator __i2, _ForwardIter __k1, 
  		 _ForwardIter __k2, forward_iterator_tag)
        {
  	size_type __dold = __i2 - __i1;
  	size_type __dmax = this->max_size();
- 	size_type __dnew = static_cast<size_type>(distance(__k1, __k2));
  
  	if (__dmax <= __dnew)
  	  __throw_length_error("basic_string::_M_replace");
  	size_type __off = __i1 - _M_ibegin();
  	_M_mutate(__off, __dold, __dnew);
- 	// Invalidated __i1, __i2
- 	if (__dnew)
- 	  _S_copy_chars(_M_data() + __off, __k1, __k2);
  	
  	return *this;
        }
  
--- 446,469 ----
        _M_replace(iterator __i1, iterator __i2, _ForwardIter __k1, 
  		 _ForwardIter __k2, forward_iterator_tag)
        {
+ 	size_type __dnew = static_cast<size_type>(distance(__k1, __k2));
  	size_type __dold = __i2 - __i1;
  	size_type __dmax = this->max_size();
  
  	if (__dmax <= __dnew)
  	  __throw_length_error("basic_string::_M_replace");
  	size_type __off = __i1 - _M_ibegin();
+ 
+ 	// Save concerned source string data in a temporary.
+ 	basic_string __temp(__k1, __k2);
  	_M_mutate(__off, __dold, __dnew);
  	
+ 	// Invalidated __i1, __i2 (and clobbered original source string
+ 	// data when destination string == source string and the string
+ 	// is unshared).
+         if (__dnew)
+ 	  _S_copy_chars(_M_data() + __off, __temp.begin(), __temp.end());
+ 
  	return *this;
        }
  
*************** namespace std
*** 473,480 ****
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT,_Traits,_Alloc>&
!     basic_string<_CharT,_Traits,_Alloc>::
      append(const basic_string& __str)
      {
        // Iff appending itself, string needs to pre-reserve the
--- 479,486 ----
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT, _Traits, _Alloc>&
!     basic_string<_CharT, _Traits, _Alloc>::
      append(const basic_string& __str)
      {
        // Iff appending itself, string needs to pre-reserve the
*************** namespace std
*** 489,496 ****
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT,_Traits,_Alloc>&
!     basic_string<_CharT,_Traits,_Alloc>::
      append(const basic_string& __str, size_type __pos, size_type __n)
      {
        // Iff appending itself, string needs to pre-reserve the
--- 495,502 ----
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT, _Traits, _Alloc>&
!     basic_string<_CharT, _Traits, _Alloc>::
      append(const basic_string& __str, size_type __pos, size_type __n)
      {
        // Iff appending itself, string needs to pre-reserve the
*************** namespace std
*** 504,511 ****
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT,_Traits,_Alloc>&
!     basic_string<_CharT,_Traits,_Alloc>::
      append(const _CharT* __s, size_type __n)
      {
        size_type __len = __n + this->size();
--- 510,517 ----
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT, _Traits, _Alloc>&
!     basic_string<_CharT, _Traits, _Alloc>::
      append(const _CharT* __s, size_type __n)
      {
        size_type __len = __n + this->size();
*************** namespace std
*** 515,522 ****
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT,_Traits,_Alloc>&
!     basic_string<_CharT,_Traits,_Alloc>::
      append(size_type __n, _CharT __c)
      {
        size_type __len = __n + this->size();
--- 521,528 ----
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT, _Traits, _Alloc>&
!     basic_string<_CharT, _Traits, _Alloc>::
      append(size_type __n, _CharT __c)
      {
        size_type __len = __n + this->size();
*************** namespace std
*** 526,536 ****
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT,_Traits,_Alloc>
      operator+(const _CharT* __lhs,
!              const basic_string<_CharT,_Traits,_Alloc>& __rhs)
      {
!       typedef basic_string<_CharT,_Traits,_Alloc> __string_type;
        typedef typename __string_type::size_type	  __size_type;
        __size_type __len = _Traits::length(__lhs);
        __string_type __str;
--- 532,542 ----
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT, _Traits, _Alloc>
      operator+(const _CharT* __lhs,
! 	      const basic_string<_CharT, _Traits, _Alloc>& __rhs)
      {
!       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
        typedef typename __string_type::size_type	  __size_type;
        __size_type __len = _Traits::length(__lhs);
        __string_type __str;
*************** namespace std
*** 541,550 ****
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT,_Traits,_Alloc>
!     operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Alloc>& __rhs)
      {
!       typedef basic_string<_CharT,_Traits,_Alloc> __string_type;
        typedef typename __string_type::size_type	  __size_type;
        __string_type __str;
        __size_type __len = __rhs.size();
--- 547,556 ----
      }
  
    template<typename _CharT, typename _Traits, typename _Alloc>
!     basic_string<_CharT, _Traits, _Alloc>
!     operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
      {
!       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
        typedef typename __string_type::size_type	  __size_type;
        __string_type __str;
        __size_type __len = __rhs.size();
*************** namespace std
*** 627,633 ****
        size_type __size = this->size();
        if (__n <= __size)
  	{
! 	  __pos = std::min(__size - __n ,__pos);
  	  const _CharT* __data = _M_data();
  	  do 
  	    {
--- 633,639 ----
        size_type __size = this->size();
        if (__n <= __size)
  	{
! 	  __pos = std::min(__size - __n, __pos);
  	  const _CharT* __data = _M_data();
  	  do 
  	    {
*************** namespace std
*** 811,817 ****
  
    template<typename _CharT, typename _Traits, typename _Alloc>
      int
!     basic_string <_CharT,_Traits,_Alloc>::
      compare(size_type __pos, size_type __n1, const _CharT* __s) const
      {
        size_type __size = this->size();
--- 817,823 ----
  
    template<typename _CharT, typename _Traits, typename _Alloc>
      int
!     basic_string <_CharT, _Traits, _Alloc>::
      compare(size_type __pos, size_type __n1, const _CharT* __s) const
      {
        size_type __size = this->size();
*************** namespace std
*** 829,835 ****
  
    template<typename _CharT, typename _Traits, typename _Alloc>
      int
!     basic_string <_CharT,_Traits,_Alloc>::
      compare(size_type __pos, size_type __n1, const _CharT* __s, 
  	    size_type __n2) const
      {
--- 835,841 ----
  
    template<typename _CharT, typename _Traits, typename _Alloc>
      int
!     basic_string <_CharT, _Traits, _Alloc>::
      compare(size_type __pos, size_type __n1, const _CharT* __s, 
  	    size_type __n2) const
      {
Index: src/string-inst.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/string-inst.cc,v
retrieving revision 1.18
diff -c -p -r1.18 string-inst.cc
*** string-inst.cc	2001/10/20 19:28:50	1.18
--- string-inst.cc	2001/10/31 08:23:46
*************** namespace std 
*** 56,77 ****
    // Only one template keyword allowed here. 
    // See core issue #46 (NAD)
    // http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#46
-   template 
-     S& 
-     S::_M_replace<S::iterator>
-     (S::iterator, S::iterator, S::iterator, S::iterator, forward_iterator_tag);
- 
-   template 
-     S& 
-     S::_M_replace<S::const_iterator>
-     (S::iterator, S::iterator, 
-      S::const_iterator, S::const_iterator, forward_iterator_tag);
- 
-   template 
-     C* 
-     S::_S_construct<S::iterator>
-     (S::iterator, S::iterator, const allocator<C>&, forward_iterator_tag);
- 
    template
      S::basic_string(C*, C*, const allocator<C>&);
  
--- 56,61 ----
*************** namespace std 
*** 81,104 ****
    template 
      S::basic_string(S::iterator, S::iterator, const allocator<C>&);
  
    template
      S&
!     S::_M_replace(S::iterator, S::iterator, C*, C*, forward_iterator_tag);  
  
    template
      S&
      S::_M_replace(S::iterator, S::iterator, const C*, const C*, 
  		  forward_iterator_tag);  
  
    template
      C*
!     S::_S_construct(const C*, const C*, const allocator<C>&, 
! 		    forward_iterator_tag);
  
    template
      C*
!     S::_S_construct (C*, C*, const allocator<C>&, 
! 		     forward_iterator_tag);
  
    template
      void
--- 65,110 ----
    template 
      S::basic_string(S::iterator, S::iterator, const allocator<C>&);
  
+   template 
+     S::basic_string(S::const_iterator, S::const_iterator, const allocator<C>&);
+ 
+   template 
+     S& 
+     S::_M_replace(S::iterator, S::iterator, S::iterator, S::iterator, 
+ 		  forward_iterator_tag);
+ 
+   template 
+     S& 
+     S::_M_replace(S::iterator, S::iterator, S::const_iterator, 
+ 		  S::const_iterator, forward_iterator_tag);
+ 
    template
      S&
!     S::_M_replace(S::iterator, S::iterator, C*, C*, forward_iterator_tag); 
  
    template
      S&
      S::_M_replace(S::iterator, S::iterator, const C*, const C*, 
  		  forward_iterator_tag);  
  
+   template 
+     C* 
+     S::_S_construct(S::iterator, S::iterator, 
+ 		    const allocator<C>&, forward_iterator_tag);
+ 
+   template 
+     C* 
+     S::_S_construct(S::const_iterator, S::const_iterator, 
+ 		    const allocator<C>&, forward_iterator_tag);
+ 
    template
      C*
!     S::_S_construct(C*, C*, const allocator<C>&, forward_iterator_tag);
  
    template
      C*
!     S::_S_construct(const C*, const C*, const allocator<C>&,
! 		    forward_iterator_tag);
  
    template
      void
Index: testsuite/21_strings/assign.cc
===================================================================
RCS file: assign.cc
diff -N assign.cc
*** /dev/null	Tue May  5 13:32:27 1998
--- assign.cc	Wed Oct 31 00:23:46 2001
***************
*** 0 ****
--- 1,46 ----
+ // 2001-10-30 Benjamin Kosnik  <bkoz@redhat.com>
+ 
+ // Copyright (C) 2001 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+ 
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ // GNU General Public License for more details.
+ 
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING.  If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+ 
+ // 21.3.5 string modifiers
+ 
+ #include <string>
+ #include <cstdio>
+ #include <testsuite_hooks.h>
+ 
+ void
+ test01()
+ {
+   bool test = true;
+ 
+   using namespace std;
+ 
+   const char* strlit = "../the long pier/Hanalei Bay/Kauai/Hawaii";
+   string aux = strlit;
+   string::size_type i = aux.rfind("/");
+   if (i != string::npos)
+     aux.assign(aux, i + 1, string::npos);
+   VERIFY(aux == "Hawaii");
+ }
+ 
+ int main()
+ { 
+   test01();
+   return 0;
+ }
Index: testsuite/21_strings/replace.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/21_strings/replace.cc,v
retrieving revision 1.5
diff -c -p -r1.5 replace.cc
*** replace.cc	2001/08/07 03:38:28	1.5
--- replace.cc	2001/10/31 08:23:46
*************** bool test01(void)
*** 52,58 ****
    // template<typename InputIter>
    //   string& replace(iterator it1, iterator it2, InputIter j1, InputIter j2)
  
- #if 1
    // with mods, from tstring.cc, from jason merrill, et. al.
    std::string X = "Hello";
    std::string x = X;
--- 52,57 ----
*************** bool test01(void)
*** 75,81 ****
  	    std::find(x.rbegin(), x.rend(), 'l').base(), ar, 
  	    ar + sizeof(ar) / sizeof(ar[0]));
    VERIFY( x == "jeHelloo" );
- #endif
  
  #ifdef DEBUG_ASSERT
    assert(test);
--- 74,79 ----
*************** bool test01(void)
*** 83,90 ****
--- 81,104 ----
    return test;
  }
  
+ void
+ test02()
+ {
+   const char* strlit = "../the long pier/Hanalei Bay/Kauai/Hawaii";
+   std::string aux = strlit;
+   aux.replace(aux.begin()+5, aux.begin()+20,
+ 	      aux.begin()+10, aux.begin()+15);
+   VERIFY(aux == "../thg piealei Bay/Kauai/Hawaii");
+   
+   aux = strlit;
+   aux.replace(aux.begin() + 10, aux.begin() + 15,
+ 	      aux.begin() + 5, aux.begin() + 20);
+   VERIFY(aux == "../the lone long pier/Hanr/Hanalei Bay/Kauai/Hawaii");
+ }
+ 
  int main()
  { 
    test01();
+   test02();
    return 0;
  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]