[PATCH] Assign(__str, __pos, __n) (take3) + Assign(__s, __n)

Paolo Carlini pcarlini@unitus.it
Sat Dec 15 07:23:00 GMT 2001


Hi all,

this is the third take. I have improved it by following Nathan's suggestion of
accounting for the special case of __pos == 0 (move is not very smart ;). In the
meanwhile I have also prepared the new assign(const _CharT* __s, size_type __n)
(similar general structure), based on
http://gcc.gnu.org/ml/libstdc++/2001-12/msg00215.html.

The patch was tested on i686-pc-linux-gnu. A separate message will report on the
corresponing benchmarks.

Cheers,
Paolo.

//////////////

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).
        * testsuite/21_strings/assign.cc (test02, test03): New tests.


diff -prN libstdc++-v3-orig/include/bits/basic_string.h
libstdc++-v3/include/bits/basic_string.h
*** libstdc++-v3-orig/include/bits/basic_string.h Mon Dec 10 15:32:28 2001
--- libstdc++-v3/include/bits/basic_string.h Sat Dec 15 13:06:52 2001
*************** namespace std
*** 477,493 ****

        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));
        }

        basic_string&
        assign(const _CharT* __s, size_type __n)
!       { return this->assign(__s, __s + __n); }

        basic_string&
        assign(const _CharT* __s)
!       { return this->assign(__s, __s + traits_type::length(__s)); }

        basic_string&
        assign(size_type __n, _CharT __c)
--- 477,529 ----

        basic_string&
        assign(const basic_string& __str, size_type __pos, size_type __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)
!       {
!  if (__n > this->max_size())
!    __throw_length_error("basic_string::assign");
!  if (_M_rep()->_M_is_shared() || __s < _M_data()
!      || __s > _M_data() + this->size())
!    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, traits_type::length(__s)); }

        basic_string&
        assign(size_type __n, _CharT __c)
diff -prN libstdc++-v3-orig/testsuite/21_strings/assign.cc
libstdc++-v3/testsuite/21_strings/assign.cc
*** libstdc++-v3-orig/testsuite/21_strings/assign.cc Wed Oct 31 09:27:20 2001
--- libstdc++-v3/testsuite/21_strings/assign.cc Sat Dec 15 13:11:25 2001
*************** test01()
*** 39,46 ****
--- 39,109 ----
    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;
  }




More information about the Libstdc++ mailing list