This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] string assign/replace fixes
- To: gcc-patches at gcc dot gnu dot org
- Subject: [v3] string assign/replace fixes
- From: Benjamin Kosnik <bkoz at redhat dot com>
- Date: Wed, 31 Oct 2001 00:26:43 -0800
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;
}