2002-01-14 Paolo Carlini <pcarlini@unitus.it>
authorPaolo Carlini <pcarlini@unitus.it>
Mon, 14 Jan 2002 19:04:15 +0000 (20:04 +0100)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 14 Jan 2002 19:04:15 +0000 (19:04 +0000)
    Nathan Myers  <ncm@cantrip.org>

* include/bits/basic_string.h
(replace(__pos, __n1, __s, __n2)): Optimize by avoiding
temporaries (i.e., call _M_replace_safe) when possible.
(replace(__pos, __n, __str)): Call replace(__pos, __n1, __s, __n2).
(replace(__pos, __n1, __s)): Call replace(__pos, __n1, __s , __n2).
(replace(__i1, __i2, __str)): Call replace(__i1, __i2, __s, __n).
(replace(__i1, __i2, __s)): Call replace(__i1, __i2, __s, __n).
(replace(__i1, __i2, __s, __n)): Call replace(__pos1, __n1, __s, __n2).
* include/bits/basic_string.tcc
(replace(__pos1, __n1, __str, __pos2, __n2)): Call
replace(__pos, __n1, __s, __n2).
* testsuite/21_strings/replace.cc (test03): New testcases.

* include/bits/basic_string.h (insert(__pos, __s, __n)):
Adjust comparison wrt overflow.

Co-Authored-By: Nathan Myers <ncm@cantrip.org>
From-SVN: r48834

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/basic_string.tcc
libstdc++-v3/testsuite/21_strings/replace.cc

index cd8fe5934773702d77239795e040068ee76ed327..ecd575702a0644d581b16b72b3ae6d226ccc5a31 100644 (file)
@@ -1,3 +1,22 @@
+2002-01-14  Paolo Carlini  <pcarlini@unitus.it>
+           Nathan Myers  <ncm@cantrip.org>
+
+       * include/bits/basic_string.h
+       (replace(__pos, __n1, __s, __n2)): Optimize by avoiding
+       temporaries (i.e., call _M_replace_safe) when possible.
+       (replace(__pos, __n, __str)): Call replace(__pos, __n1, __s, __n2).
+       (replace(__pos, __n1, __s)): Call replace(__pos, __n1, __s , __n2).
+       (replace(__i1, __i2, __str)): Call replace(__i1, __i2, __s, __n).
+       (replace(__i1, __i2, __s)): Call replace(__i1, __i2, __s, __n).
+       (replace(__i1, __i2, __s, __n)): Call replace(__pos1, __n1, __s, __n2).
+       * include/bits/basic_string.tcc
+       (replace(__pos1, __n1, __str, __pos2, __n2)): Call
+       replace(__pos, __n1, __s, __n2).
+       * testsuite/21_strings/replace.cc (test03): New testcases.
+
+       * include/bits/basic_string.h (insert(__pos, __s, __n)):
+       Adjust comparison wrt overflow.
+       
 2002-01-12  Benjamin Kosnik  <bkoz@redhat.com>
 
        * include/Makefile.am (std_headers_rename): New variable.
index d25d9def39b00b3008c2fea79b17f32383356273..5756e9eac44bafb6934f583fba0485ccd18b6ad5 100644 (file)
@@ -1,6 +1,7 @@
 // Components for manipulating sequences of characters -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// 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
@@ -551,7 +552,7 @@ namespace std
        const size_type __size = this->size();
        if (__pos > __size)
          __throw_out_of_range("basic_string::insert");
-       if (__n + __size > this->max_size())
+       if (__size > this->max_size() - __n)
          __throw_length_error("basic_string::insert");
        if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
            || less<const _CharT*>()(_M_data() + __size, __s))
@@ -626,10 +627,7 @@ namespace std
 
       basic_string& 
       replace(size_type __pos, size_type __n, const basic_string& __str)
-      { 
-       return this->replace(_M_check(__pos), _M_fold(__pos, __n),
-                             __str.begin(), __str.end()); 
-      }
+      { return this->replace(__pos, __n, __str._M_data(), __str.size()); }
 
       basic_string& 
       replace(size_type __pos1, size_type __n1, const basic_string& __str,
@@ -639,36 +637,41 @@ namespace std
       replace(size_type __pos, size_type __n1, const _CharT* __s,
              size_type __n2)
       { 
-       return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
-                            __s, __s + __n2); 
+       const size_type __size = this->size();
+       if (__pos > __size)
+         __throw_out_of_range("basic_string::replace");
+       if (__size - __n1 > this->max_size() - __n2)
+         __throw_length_error("basic_string::replace");
+       const bool __testn1 = __n1 < __size - __pos;
+       const size_type __foldn1 = __testn1 ? __n1 : __size - __pos;
+       if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
+           || less<const _CharT*>()(_M_data() + __size, __s))
+         return _M_replace_safe(_M_ibegin() + __pos,
+                                _M_ibegin() + __pos + __foldn1, __s, __s + __n2);      
+       else return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
+                                 __s, __s + __n2); 
       }
 
       basic_string& 
       replace(size_type __pos, size_type __n1, const _CharT* __s)
-      { 
-       return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
-                            __s, __s + traits_type::length(__s)); 
-      }
+      { return this->replace(__pos, __n1, __s, traits_type::length(__s)); }
 
       basic_string& 
       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
-      { 
-       return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c);
-      }
+      { return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); }
 
       basic_string& 
       replace(iterator __i1, iterator __i2, const basic_string& __str)
-      { return this->replace(__i1, __i2, __str.begin(), __str.end()); }
+      { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }
 
       basic_string& 
       replace(iterator __i1, iterator __i2,
                            const _CharT* __s, size_type __n)
-      { return this->replace(__i1, __i2, __s, __s + __n); }
+      { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n); }
 
       basic_string& 
       replace(iterator __i1, iterator __i2, const _CharT* __s)
-      { return this->replace(__i1, __i2, __s, 
-                            __s + traits_type::length(__s)); }
+      { return this->replace(__i1, __i2, __s, traits_type::length(__s)); }
 
       basic_string& 
       replace(iterator __i1, iterator __i2, size_type __n, _CharT __c);
index 63a9864a9d066d6afcbbbb62ecad9f20650d26cf..b57c7f642f998b5e3791259c6b56c4a3af2bb451 100644 (file)
@@ -1,6 +1,7 @@
 // Components for manipulating sequences of characters -*- C++ -*-
 
-// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+// 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
@@ -543,9 +544,13 @@ namespace std
     replace(size_type __pos1, size_type __n1, const basic_string& __str,
            size_type __pos2, size_type __n2)
     {
-      return this->replace(_M_check(__pos1), _M_fold(__pos1, __n1),
-                          __str._M_check(__pos2), 
-                          __str._M_fold(__pos2, __n2));      
+      const size_type __strsize = __str.size();
+      if (__pos2 > __strsize)
+       __throw_out_of_range("basic_string::replace");
+      const bool __testn2 = __n2 < __strsize - __pos2;
+      const size_type __foldn2 = __testn2 ? __n2 : __strsize - __pos2;
+      return this->replace(__pos1, __n1,
+                          __str._M_data() + __pos2, __foldn2);      
     }
 
   template<typename _CharT, typename _Traits, typename _Alloc>
index b42ae8d3fa66bfb6657696489a0a997d7bd0ff11..aeaba190ecc5104b414f4b8a041a771a603feb2b 100644 (file)
@@ -1,6 +1,6 @@
 // 1999-06-10 bkoz
 
-// Copyright (C) 1994, 1999 Free Software Foundation, Inc.
+// Copyright (C) 1994, 1999, 2001, 2002 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
@@ -96,9 +96,53 @@ test02()
   VERIFY(aux == "../the lone long pier/Hanr/Hanalei Bay/Kauai/Hawaii");
 }
 
+// Some more miscellaneous tests
+void
+test03()
+{
+  const char* title01 = "nine types of ambiguity";
+  const char* title02 = "ultra";
+  std::string str01 = title01;
+  std::string str02 = title02;
+
+  str01.replace(0, 4, str02);
+  VERIFY(str01 == "ultra types of ambiguity");
+
+  str01.replace(15, 9, str02, 2, 2);
+  VERIFY(str01 == "ultra types of tr");
+
+  str01 = title01;
+  str02.replace(0, 0, str01, 0, std::string::npos);
+  VERIFY(str02 == "nine types of ambiguityultra");
+
+  str02.replace(11, 2, title02, 5);
+  VERIFY(str02 == "nine types ultra ambiguityultra");
+
+  str02.replace(11, 5, title01, 2);
+  VERIFY(str02 == "nine types ni ambiguityultra");
+
+  str01.replace(str01.size(), 0, title02);
+  VERIFY(str01 == "nine types of ambiguityultra");
+  
+  str01 = title01;
+  str02 = title02;
+  str01.replace(str01.begin(), str01.end(), str02);
+  VERIFY(str01 == "ultra");
+
+  str01.replace(str01.begin(), str01.begin(), title01, 4);
+  VERIFY(str01 == "nineultra");
+
+  str01.replace(str01.end(), str01.end(), title01 + 5, 5);
+  VERIFY(str01 == "nineultratypes");
+  
+  str01.replace(str01.begin(), str01.end(), title02);
+  VERIFY(str01 == "ultra");
+}
+
 int main()
 { 
   test01();
   test02();
+  test03();
   return 0;
 }