2001-12-15 Paolo Carlini <pcarlini@unitus.it>
authorPaolo Carlini <pcarlini@unitus.it>
Sun, 16 Dec 2001 01:02:17 +0000 (02:02 +0100)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sun, 16 Dec 2001 01:02:17 +0000 (01:02 +0000)
            Nathan Myers  <ncm@cantrip.org>

        * include/bits/basic_string.h
(assign(__str, __pos, __n), assign(__s, __n)):  Optimize
by avoiding unnecessary temporaries.
(assign(__s)): Call assign(__s, __n).
* include/bits/basic_string.tcc (_M_replace_safe): Adjust comment.
* include/bits/std_string.h: include stl_function.h.
        * testsuite/21_strings/assign.cc (test02, test03): New tests.

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

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

index 076157a..ea411a9 100644 (file)
@@ -1,3 +1,14 @@
+2001-12-15  Paolo Carlini  <pcarlini@unitus.it>
+            Nathan Myers  <ncm@cantrip.org>
+
+       * include/bits/basic_string.h
+       (assign(__str, __pos, __n), assign(__s, __n)):  Optimize
+       by avoiding unnecessary temporaries.
+       (assign(__s)): Call assign(__s, __n).
+       * include/bits/basic_string.tcc (_M_replace_safe): Adjust comment.
+       * include/bits/std_string.h: include stl_function.h.
+       * testsuite/21_strings/assign.cc (test02, test03): New tests.
+
 2001-12-15  Benjamin Kosnik  <bkoz@redhat.com>
 
        * acinclude.m4 (GLIBCPP_ENABLE_CLOCALE): Enable gnu locale model
index 6f9afe1..af550c9 100644 (file)
@@ -477,17 +477,53 @@ namespace std
 
       basic_string& 
       assign(const basic_string& __str, size_type __pos, size_type __n)
-      { 
-       return this->assign(__str._M_check(__pos), __str._M_fold(__pos, __n)); 
+      {
+       if (__pos > __str.size())
+         __throw_out_of_range("basic_string::assign");
+       if (_M_rep()->_M_is_shared() || _M_rep() != __str._M_rep())
+         return _M_replace_safe(_M_ibegin(), _M_iend(), 
+                                __str._M_check(__pos),
+                                __str._M_fold(__pos, __n));
+       else
+         {
+           // Work in-place.
+           bool __testn = __n < __str.size() - __pos;
+           const size_type __newsize = __testn ? __n : __str.size() - __pos;
+           // Avoid move, if possible.
+           if (__pos >= __newsize)
+             traits_type::copy(_M_data(), __str._M_data() + __pos, __newsize);
+           else if (__pos)           
+             traits_type::move(_M_data(), __str._M_data() + __pos, __newsize);
+           // else nothing (avoid calling move unnecessarily)
+           _M_rep()->_M_length = __newsize;
+           return *this;
+         }
       }
 
       basic_string& 
       assign(const _CharT* __s, size_type __n)
-      { return this->assign(__s, __s + __n); }
+      {
+       if (__n > this->max_size())
+         __throw_length_error("basic_string::assign");
+       if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
+           || less<const _CharT*>()(_M_data() + this->size(), __s))
+         return _M_replace_safe(_M_ibegin(), _M_iend(), __s, __s + __n);
+       else
+         {
+           // Work in-place
+           const size_type __pos = __s - _M_data();
+           if (__pos >= __n)
+             traits_type::copy(_M_data(), __s, __n);
+           else if (__pos)
+             traits_type::move(_M_data(), __s, __n);
+           _M_rep()->_M_length = __n;
+           return *this;
+         }
+      }
 
       basic_string& 
       assign(const _CharT* __s)
-      { return this->assign(__s, __s + traits_type::length(__s)); }
+      { return this->assign(__s, traits_type::length(__s)); }
 
       basic_string& 
       assign(size_type __n, _CharT __c)
index 69638e2..63a9864 100644 (file)
@@ -512,7 +512,8 @@ namespace std
   // This is a special replace helper, which does not buffer internally
   // and can be used in the "safe" situations involving forward-iterators,
   // i.e., when source and destination ranges are known to not overlap.
-  // Presently, is called by _M_replace and by the various append.
+  // Presently, is called by _M_replace, by the various append and by
+  // the assigns.
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _ForwardIter>
       basic_string<_CharT, _Traits, _Alloc>&
index 09347a9..d93fa20 100644 (file)
@@ -48,6 +48,7 @@
 #include <bits/type_traits.h>
 #include <bits/std_iosfwd.h>   // For operators >>, <<, and getline decls.
 #include <bits/stl_iterator.h>
+#include <bits/stl_function.h>  // For less
 #include <bits/basic_string.h>
 
 #ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
index 271ef65..1d7db1c 100644 (file)
@@ -39,8 +39,71 @@ test01()
   VERIFY(aux == "Hawaii");
 }
 
+// assign(const basic_string& __str, size_type __pos, size_type __n)
+void
+test02()
+{
+  bool test = true;
+
+  using namespace std;
+  
+  string one = "Selling England by the pound";
+  string two = one;
+  string three = "Brilliant trees";
+
+  one.assign(one, 8, 100);
+  VERIFY( one == "England by the pound" );
+
+  one.assign(one, 8, 0);
+  VERIFY( one == "" );
+  one.assign(two, 8, 7);
+  VERIFY( one == "England" );
+
+  one.assign(three, 10, 100);
+  VERIFY( one == "trees" );
+
+  three.assign(one, 0, 3);
+  VERIFY( three == "tre" );
+}
+
+// assign(const _CharT* __s, size_type __n)
+// assign(const _CharT* __s)
+void
+test03()
+{
+  bool test = true;
+
+  using namespace std;
+  string one; 
+  string two;
+  string three = two;
+  const char * source = "Selling England by the pound";
+
+  one.assign(source);
+  VERIFY( one == "Selling England by the pound" );
+
+  one.assign(source, 28);
+  VERIFY( one == "Selling England by the pound" );
+
+  two.assign(source, 7);
+  VERIFY( two == "Selling" );
+  
+  one.assign(one.c_str() + 8, 20);
+  VERIFY( one == "England by the pound" );
+
+  one.assign(one.c_str() + 8, 6);
+  VERIFY( one == "by the" );
+}
+
+
+
 int main()
 { 
   test01();
+  test02();
+  test03();
+
   return 0;
 }