aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@unitus.it>2001-12-16 02:02:17 +0100
committerPaolo Carlini <paolo@gcc.gnu.org>2001-12-16 01:02:17 +0000
commitbd1f473825af96053542ff6d3ac518a77c95b4af (patch)
tree712f37fa4aadfa8e07f17a38c0faf08ecd8f3174
parent226ada7a41dba4d02def08367ed1b66199d6e472 (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--libstdc++-v3/include/bits/basic_string.h44
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc3
-rw-r--r--libstdc++-v3/include/bits/std_string.h1
-rw-r--r--libstdc++-v3/testsuite/21_strings/assign.cc63
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;
}