+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
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)
// 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>&
#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
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;
}