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
This commit is contained in:
Paolo Carlini 2001-12-16 02:02:17 +01:00 committed by Paolo Carlini
parent 226ada7a41
commit bd1f473825
5 changed files with 117 additions and 5 deletions

View File

@ -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

View File

@ -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)

View File

@ -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>&

View File

@ -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

View File

@ -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;
}