This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA, PATCH] A new assign(__str, __pos, __n)


Hi all,

taking into account to my best all the indications Nathan gave in the last days,
I'm currently testing optimized implementations of those basic_string members
which do not have the source data specified in terms of iterators. After the
trivial case of the assign(s) (plus operator+, and co), this is the natural
second step, in my opinion.

As an example I propose a new implementation of assign(__str, __pos, __n). In
order to better test it I have also enriched a bit the testsuite entry for
21_strings/assign.c.

For sure its speed is greater than that of the current implementation (which
ends up calling the general "paranoic" _M_replace which always buffers; here, on
the other hand, we *never* buffer :-) but I don't have numbers, yet.

Cheers,
Paolo.

P.S. The patch is fully functional, reg-tested i686-pc-linux-gnu.

//------------------------------

      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 (__n)
           {
             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 memmove, if possible.
                  if (__pos >= __newsize)
                    traits_type::copy(_M_data(), __str._M_data() + __pos,
__newsize);
                  else
                    traits_type::move(_M_data(), __str._M_data() + __pos,
__newsize);
                  this->resize(__newsize);
                  return *this;
               }
           }
         else this->resize(0);
         return *this;
      }

//------------------------------


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

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 Thu Dec 13 23:12:45 2001
*************** namespace std
*** 477,484 ****

        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&
--- 477,507 ----

        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 (__n)
!    {
!      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 memmove, if possible.
!   if (__pos >= __newsize)
!     traits_type::copy(_M_data(), __str._M_data() + __pos, __newsize);
!   else
!     traits_type::move(_M_data(), __str._M_data() + __pos, __newsize);
!   this->resize(__newsize);
!   return *this;
!        }
!    }
!  else this->resize(0);
!  return *this;
        }

        basic_string&
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 Fri Dec 14 00:08:40 2001
*************** test01()
*** 39,46 ****
--- 39,75 ----
    VERIFY(aux == "Hawaii");
  }

+ 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");
+ }
+
  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]