diff options
author | Paolo Carlini <pcarlini@unitus.it> | 2001-12-16 02:02:17 +0100 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2001-12-16 01:02:17 +0000 |
commit | bd1f473825af96053542ff6d3ac518a77c95b4af (patch) | |
tree | 712f37fa4aadfa8e07f17a38c0faf08ecd8f3174 | |
parent | 226ada7a41dba4d02def08367ed1b66199d6e472 (diff) | |
download | gcc-bd1f473825af96053542ff6d3ac518a77c95b4af.zip gcc-bd1f473825af96053542ff6d3ac518a77c95b4af.tar.gz gcc-bd1f473825af96053542ff6d3ac518a77c95b4af.tar.bz2 |
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.
Co-Authored-By: Nathan Myers <ncm@cantrip.org>
From-SVN: r48053
-rw-r--r-- | libstdc++-v3/ChangeLog | 11 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/basic_string.h | 44 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/basic_string.tcc | 3 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/std_string.h | 1 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/21_strings/assign.cc | 63 |
5 files changed, 117 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 076157a..ea411a9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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 diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 6f9afe1..af550c9 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -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) diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 69638e2..63a9864 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -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>& diff --git a/libstdc++-v3/include/bits/std_string.h b/libstdc++-v3/include/bits/std_string.h index 09347a9..d93fa20 100644 --- a/libstdc++-v3/include/bits/std_string.h +++ b/libstdc++-v3/include/bits/std_string.h @@ -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 diff --git a/libstdc++-v3/testsuite/21_strings/assign.cc b/libstdc++-v3/testsuite/21_strings/assign.cc index 271ef65..1d7db1c 100644 --- a/libstdc++-v3/testsuite/21_strings/assign.cc +++ b/libstdc++-v3/testsuite/21_strings/assign.cc @@ -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; } |