[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