From: Paolo Carlini Date: Mon, 25 Oct 2004 08:45:04 +0000 (+0000) Subject: basic_string.h (_Rep::_M_is_safe, [...]): New, use througout. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;ds=sidebyside;h=ec61e852bc917b45c288e17fa4f1cb06145cf95e;p=gcc.git basic_string.h (_Rep::_M_is_safe, [...]): New, use througout. 2004-10-25 Paolo Carlini * include/bits/basic_string.h (_Rep::_M_is_safe, _M_check_length, _M_move, _M_copy, _M_assign): New, use througout. (operator+=(_CharT)): Define in terms of push_back. (append(const basic_string&)): Define here, inline, and simplify, don't use the full _M_replace_safe. (append(size_type, _CharT)): Likewise, don't use _M_replace_aux. (push_back): Likewise. (assign(const basic_string&)): Define here, inline. * include/bits/basic_string.tcc (append(const _CharT* s, size_type): Fix: when s points inside the _Rep, upon reallocation (reserve) we were copying from deallocated memory. (append(const basic_string&, size_type, size_type)): Simplify, don't use _M_replace_safe. (replace(size_type, size_type, const _CharT*, size_type)): Slightly tweak. (reserve): Likewise. * testsuite/21_strings/basic_string/append/char/2.cc: New. * testsuite/21_strings/basic_string/append/char/3.cc: Likewise. * testsuite/21_strings/basic_string/append/wchar_t/2.cc: Likewise. * testsuite/21_strings/basic_string/append/wchar_t/3.cc: Likewise. * testsuite/21_strings/basic_string/assign/char/3.cc: Remove junk. * testsuite/21_strings/basic_string/assign/wchar_t/3.cc: Likewise. From-SVN: r89526 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f0c2da60045..9d8d3f2c0f6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,29 @@ +2004-10-25 Paolo Carlini + + * include/bits/basic_string.h (_Rep::_M_is_safe, _M_check_length, + _M_move, _M_copy, _M_assign): New, use througout. + (operator+=(_CharT)): Define in terms of push_back. + (append(const basic_string&)): Define here, inline, and simplify, + don't use the full _M_replace_safe. + (append(size_type, _CharT)): Likewise, don't use _M_replace_aux. + (push_back): Likewise. + (assign(const basic_string&)): Define here, inline. + * include/bits/basic_string.tcc (append(const _CharT* s, size_type): + Fix: when s points inside the _Rep, upon reallocation (reserve) we + were copying from deallocated memory. + (append(const basic_string&, size_type, size_type)): Simplify, + don't use _M_replace_safe. + (replace(size_type, size_type, const _CharT*, size_type)): Slightly + tweak. + (reserve): Likewise. + * testsuite/21_strings/basic_string/append/char/2.cc: New. + * testsuite/21_strings/basic_string/append/char/3.cc: Likewise. + * testsuite/21_strings/basic_string/append/wchar_t/2.cc: Likewise. + * testsuite/21_strings/basic_string/append/wchar_t/3.cc: Likewise. + + * testsuite/21_strings/basic_string/assign/char/3.cc: Remove junk. + * testsuite/21_strings/basic_string/assign/wchar_t/3.cc: Likewise. + 2004-10-23 Andrew Pinski * testsuite/ext/mt_allocator/deallocate_global-2.c: diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 5471299045e..9900798339a 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -185,6 +185,14 @@ namespace std _M_is_shared() const { return this->_M_refcount > 0; } + // True if source and destination do not overlap. + bool + _M_is_safe(const _CharT* __data, const _CharT* __s) const + { + return (less()(__s, __data) + || less()(__data + this->_M_length, __s)); + } + void _M_set_leaked() { this->_M_refcount = -1; } @@ -302,6 +310,13 @@ namespace std return __pos; } + void + _M_check_length(size_type __n1, size_type __n2, const char* __s) const + { + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N(__s)); + } + // NB: _M_limit doesn't check for a bad __pos value. size_type _M_limit(size_type __pos, size_type __off) const @@ -310,6 +325,35 @@ namespace std return __testoff ? __off : this->size() - __pos; } + // When __n = 1 way faster than the general multichar + // traits_type::copy/move/assign. + static void + _M_copy(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::copy(__d, __s, __n); + } + + static void + _M_move(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::move(__d, __s, __n); + } + + static void + _M_assign(_CharT* __d, size_type __n, _CharT __c) + { + if (__n == 1) + traits_type::assign(*__d, __c); + else + traits_type::assign(__d, __n, __c); + } + // _S_copy_chars is a separate template to permit specialization // to optimize for the common case of pointers as iterators. template @@ -330,11 +374,11 @@ namespace std static void _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) - { traits_type::copy(__p, __k1, __k2 - __k1); } + { _M_copy(__p, __k1, __k2 - __k1); } static void _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) - { traits_type::copy(__p, __k1, __k2 - __k1); } + { _M_copy(__p, __k1, __k2 - __k1); } void _M_mutate(size_type __pos, size_type __len1, size_type __len2); @@ -721,7 +765,10 @@ namespace std */ basic_string& operator+=(_CharT __c) - { return this->append(size_type(1), __c); } + { + this->push_back(__c); + return *this; + } /** * @brief Append a string to this string. @@ -729,7 +776,19 @@ namespace std * @return Reference to this string. */ basic_string& - append(const basic_string& __str); + append(const basic_string& __str) + { + const size_type __size = __str.size(); + if (__size) + { + const size_type __len = __size + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_copy(_M_data() + this->size(), __str._M_data(), __size); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } /** * @brief Append a substring. @@ -777,7 +836,18 @@ namespace std */ basic_string& append(size_type __n, _CharT __c) - { return _M_replace_aux(this->size(), size_type(0), __n, __c); } + { + if (__n) + { + _M_check_length(size_type(0), __n, "basic_string::append"); + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_assign(_M_data() + this->size(), __n, __c); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } /** * @brief Append a range of characters. @@ -798,7 +868,13 @@ namespace std */ void push_back(_CharT __c) - { _M_replace_aux(this->size(), size_type(0), size_type(1), __c); } + { + const size_type __len = 1 + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + traits_type::assign(_M_data()[this->size()], __c); + _M_rep()->_M_set_length_and_sharable(__len); + } /** * @brief Set value to contents of another string. @@ -806,7 +882,18 @@ namespace std * @return Reference to this string. */ basic_string& - assign(const basic_string& __str); + assign(const basic_string& __str) + { + if (_M_rep() != __str._M_rep()) + { + // XXX MT + const allocator_type __a = this->get_allocator(); + _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); + _M_rep()->_M_dispose(__a); + _M_data(__tmp); + } + return *this; + } /** * @brief Set value to a substring of a string. @@ -909,7 +996,8 @@ namespace std * of the string doesn't change if an error is thrown. */ template - void insert(iterator __p, _InputIterator __beg, _InputIterator __end) + void + insert(iterator __p, _InputIterator __beg, _InputIterator __end) { this->replace(__p, __p, __beg, __end); } /** @@ -1370,13 +1458,10 @@ namespace std _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, _CharT __c) { - if (this->max_size() - (this->size() - __n1) < __n2) - __throw_length_error(__N("basic_string::_M_replace_aux")); + _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); _M_mutate(__pos1, __n1, __n2); - if (__n2 == 1) - _M_data()[__pos1] = __c; - else if (__n2) - traits_type::assign(_M_data() + __pos1, __n2, __c); + if (__n2) + _M_assign(_M_data() + __pos1, __n2, __c); return *this; } @@ -1385,10 +1470,8 @@ namespace std size_type __n2) { _M_mutate(__pos1, __n1, __n2); - if (__n2 == 1) - _M_data()[__pos1] = *__s; - else if (__n2) - traits_type::copy(_M_data() + __pos1, __s, __n2); + if (__n2) + _M_copy(_M_data() + __pos1, __s, __n2); return *this; } diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 583e447780d..40634978712 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -101,7 +101,7 @@ namespace std ++__beg; } _Rep* __r = _Rep::_S_create(__len, size_type(0), __a); - traits_type::copy(__r->_M_refdata(), __buf, __len); + _M_copy(__r->_M_refdata(), __buf, __len); try { while (__beg != __end) @@ -110,8 +110,7 @@ namespace std { // Allocate more space. _Rep* __another = _Rep::_S_create(__len + 1, __len, __a); - traits_type::copy(__another->_M_refdata(), - __r->_M_refdata(), __len); + _M_copy(__another->_M_refdata(), __r->_M_refdata(), __len); __r->_M_destroy(__a); __r = __another; } @@ -170,7 +169,7 @@ namespace std // Check for out_of_range and length_error exceptions. _Rep* __r = _Rep::_S_create(__n, size_type(0), __a); if (__n) - traits_type::assign(__r->_M_refdata(), __n, __c); + _M_assign(__r->_M_refdata(), __n, __c); __r->_M_set_length_and_sharable(__n); return __r->_M_refdata(); @@ -243,42 +242,69 @@ namespace std template basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>:: - assign(const basic_string& __str) + assign(const _CharT* __s, size_type __n) { - if (_M_rep() != __str._M_rep()) + __glibcxx_requires_string_len(__s, __n); + _M_check_length(this->size(), __n, "basic_string::assign"); + if (_M_rep()->_M_is_safe(_M_data(), __s) || _M_rep()->_M_is_shared()) + return _M_replace_safe(size_type(0), this->size(), __s, __n); + else { - // XXX MT - const allocator_type __a = this->get_allocator(); - _CharT* __tmp = __str._M_rep()->_M_grab(__a, __str.get_allocator()); - _M_rep()->_M_dispose(__a); - _M_data(__tmp); + // 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_set_length_and_sharable(__n); + return *this; + } + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + if (__n) + { + _M_check_length(size_type(0), __n, "basic_string::append"); + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + { + if (_M_rep()->_M_is_safe(_M_data(), __s)) + this->reserve(__len); + else + { + const size_type __off = __s - _M_data(); + this->reserve(__len); + __s = _M_data() + __off; + } + } + _M_copy(_M_data() + this->size(), __s, __n); + _M_rep()->_M_set_length_and_sharable(__len); } return *this; } - template - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - assign(const _CharT* __s, size_type __n) - { - __glibcxx_requires_string_len(__s, __n); - if (__n > this->max_size()) - __throw_length_error(__N("basic_string::assign")); - if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) - || less()(_M_data() + this->size(), __s)) - return _M_replace_safe(size_type(0), this->size(), __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_set_length_and_sharable(__n); - return *this; - } - } + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + append(const basic_string& __str, size_type __pos, size_type __n) + { + __str._M_check(__pos, "basic_string::append"); + __n = __str._M_limit(__pos, __n); + if (__n) + { + const size_type __len = __n + this->size(); + if (__len > this->capacity() || _M_rep()->_M_is_shared()) + this->reserve(__len); + _M_copy(_M_data() + this->size(), __str._M_data() + __pos, __n); + _M_rep()->_M_set_length_and_sharable(__len); + } + return *this; + } template basic_string<_CharT, _Traits, _Alloc>& @@ -287,29 +313,25 @@ namespace std { __glibcxx_requires_string_len(__s, __n); _M_check(__pos, "basic_string::insert"); - if (this->max_size() - this->size() < __n) - __throw_length_error(__N("basic_string::insert")); - if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) - || less()(_M_data() + this->size(), __s)) + _M_check_length(size_type(0), __n, "basic_string::insert"); + if (_M_rep()->_M_is_safe(_M_data(), __s) || _M_rep()->_M_is_shared()) return _M_replace_safe(__pos, size_type(0), __s, __n); else { - // Work in-place. If _M_mutate reallocates the string, __s - // does not point anymore to valid data, therefore we save its - // offset, then we restore it. + // Work in-place. const size_type __off = __s - _M_data(); _M_mutate(__pos, 0, __n); __s = _M_data() + __off; _CharT* __p = _M_data() + __pos; if (__s + __n <= __p) - traits_type::copy(__p, __s, __n); + _M_copy(__p, __s, __n); else if (__s >= __p) - traits_type::copy(__p, __s + __n, __n); + _M_copy(__p, __s + __n, __n); else { const size_type __nleft = __p - __s; - traits_type::copy(__p, __s, __nleft); - traits_type::copy(__p + __nleft, __p + __n, __n - __nleft); + _M_copy(__p, __s, __nleft); + _M_copy(__p + __nleft, __p + __n, __n - __nleft); } return *this; } @@ -324,24 +346,18 @@ namespace std __glibcxx_requires_string_len(__s, __n2); _M_check(__pos, "basic_string::replace"); __n1 = _M_limit(__pos, __n1); - if (this->max_size() - (this->size() - __n1) < __n2) - __throw_length_error(__N("basic_string::replace")); + _M_check_length(__n1, __n2, "basic_string::replace"); bool __left; - if (_M_rep()->_M_is_shared() || less()(__s, _M_data()) - || less()(_M_data() + this->size(), __s)) + if (_M_rep()->_M_is_safe(_M_data(), __s) || _M_rep()->_M_is_shared()) return _M_replace_safe(__pos, __n1, __s, __n2); else if ((__left = __s + __n2 <= _M_data() + __pos) || _M_data() + __pos + __n1 <= __s) { // Work in-place: non-overlapping case. - const size_type __off = __s - _M_data(); + size_type __off = __s - _M_data(); + __left ? __off : (__off += __n2 - __n1); _M_mutate(__pos, __n1, __n2); - if (__left) - traits_type::copy(_M_data() + __pos, - _M_data() + __off, __n2); - else - traits_type::copy(_M_data() + __pos, - _M_data() + __off + __n2 - __n1, __n2); + _M_copy(_M_data() + __pos, _M_data() + __off, __n2); return *this; } else @@ -396,19 +412,19 @@ namespace std _Rep* __r = _Rep::_S_create(__new_size, this->capacity(), __a); if (__pos) - traits_type::copy(__r->_M_refdata(), _M_data(), __pos); + _M_copy(__r->_M_refdata(), _M_data(), __pos); if (__how_much) - traits_type::copy(__r->_M_refdata() + __pos + __len2, - _M_data() + __pos + __len1, __how_much); + _M_copy(__r->_M_refdata() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); _M_rep()->_M_dispose(__a); _M_data(__r->_M_refdata()); } else if (__how_much && __len1 != __len2) { - // Work in-place - traits_type::move(_M_data() + __pos + __len2, - _M_data() + __pos + __len1, __how_much); + // Work in-place. + _M_move(_M_data() + __pos + __len2, + _M_data() + __pos + __len1, __how_much); } _M_rep()->_M_set_length_and_sharable(__new_size); } @@ -420,8 +436,6 @@ namespace std { if (__res != this->capacity() || _M_rep()->_M_is_shared()) { - if (__res > this->max_size()) - __throw_length_error(__N("basic_string::reserve")); // Make sure we don't shrink below the current size if (__res < this->size()) __res = this->size(); @@ -539,7 +553,7 @@ namespace std _Rep* __r = _Rep::_S_create(__requested_cap, this->_M_capacity, __alloc); if (this->_M_length) - traits_type::copy(__r->_M_refdata(), _M_refdata(), this->_M_length); + _M_copy(__r->_M_refdata(), _M_refdata(), this->_M_length); __r->_M_set_length_and_sharable(this->_M_length); return __r->_M_refdata(); @@ -550,9 +564,8 @@ namespace std basic_string<_CharT, _Traits, _Alloc>:: resize(size_type __n, _CharT __c) { - if (__n > max_size()) - __throw_length_error(__N("basic_string::resize")); const size_type __size = this->size(); + _M_check_length(__size, __n, "basic_string::resize"); if (__size < __n) this->append(__n - __size, __c); else if (__n < __size) @@ -569,57 +582,11 @@ namespace std { const basic_string __s(__k1, __k2); const size_type __n1 = __i2 - __i1; - if (this->max_size() - (this->size() - __n1) < __s.size()) - __throw_length_error(__N("basic_string::_M_replace_dispatch")); + _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch"); return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(), __s.size()); } - - template - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - append(const basic_string& __str) - { - // Iff appending itself, string needs to pre-reserve the - // correct size so that _M_mutate does not clobber the - // pointer __str._M_data() formed here. - const size_type __size = __str.size(); - const size_type __len = __size + this->size(); - if (__len > this->capacity()) - this->reserve(__len); - return _M_replace_safe(this->size(), size_type(0), __str._M_data(), - __str.size()); - } - - template - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - append(const basic_string& __str, size_type __pos, size_type __n) - { - // Iff appending itself, string needs to pre-reserve the - // correct size so that _M_mutate does not clobber the - // pointer __str._M_data() formed here. - __str._M_check(__pos, "basic_string::append"); - __n = __str._M_limit(__pos, __n); - const size_type __len = __n + this->size(); - if (__len > this->capacity()) - this->reserve(__len); - return _M_replace_safe(this->size(), size_type(0), __str._M_data() - + __pos, __n); - } - - template - basic_string<_CharT, _Traits, _Alloc>& - basic_string<_CharT, _Traits, _Alloc>:: - append(const _CharT* __s, size_type __n) - { - __glibcxx_requires_string_len(__s, __n); - const size_type __len = __n + this->size(); - if (__len > this->capacity()) - this->reserve(__len); - return _M_replace_safe(this->size(), size_type(0), __s, __n); - } - + template basic_string<_CharT, _Traits, _Alloc> operator+(const _CharT* __lhs, @@ -659,7 +626,7 @@ namespace std __n = _M_limit(__pos, __n); __glibcxx_requires_string_len(__s, __n); if (__n) - traits_type::copy(__s, _M_data() + __pos, __n); + _M_copy(__s, _M_data() + __pos, __n); // 21.3.5.7 par 3: do not append null. (good.) return __n; } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/append/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/append/char/1.cc index 8fd48e555b9..cf131ac109c 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/append/char/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/append/char/1.cc @@ -18,7 +18,7 @@ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. -// 21.3.5.3 basic_string::assign +// 21.3.5.2 basic_string::append #include #include diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/append/char/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string/append/char/2.cc new file mode 100644 index 00000000000..d381e2a03c6 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/append/char/2.cc @@ -0,0 +1,67 @@ +// 2004-25-10 Paolo Carlini + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 21.3.5 string modifiers + +#include +#include + +// append(const _CharT* __s, size_type __n) +// append(const _CharT* __s) +void +test02() +{ + bool test __attribute__((unused)) = true; + + using namespace std; + + string one; + string two; + string three; + const char * source = "Written in your eyes"; + + one.append(source); + VERIFY( one == "Written in your eyes" ); + + two.append(source, 20); + VERIFY( two == "Written in your eyes" ); + + three.append(source, 7); + VERIFY( three == "Written" ); + + three.clear(); + three.append(source + 8, 2); + VERIFY( three == "in" ); + + one.append(one.c_str(), 20); + VERIFY( one == "Written in your eyesWritten in your eyes" ); + + two.append(two.c_str() + 16, 4); + VERIFY( two == "Written in your eyeseyes" ); + + two.append(two.c_str(), 3); + VERIFY( two == "Written in your eyeseyesWri" ); +} + +int main() +{ + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/append/char/3.cc b/libstdc++-v3/testsuite/21_strings/basic_string/append/char/3.cc new file mode 100644 index 00000000000..f45943d49bc --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/append/char/3.cc @@ -0,0 +1,56 @@ +// 2004-25-10 Paolo Carlini + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 21.3.5 string modifiers + +#include +#include + +// Upon reallocation (basic_string::reserve) we were copying from +// deallocated memory. +void +test03() +{ + bool test __attribute__((unused)) = true; + + using namespace std; + + const char * source = "Kesto"; + + for (unsigned i = 0; i < 10; ++i) + { + string one(source); + string two(source); + for (unsigned j = 0; j < 18; ++j) + { + VERIFY( one == two ); + one.append(one); + one += 'x'; + two.append(two.c_str(), two.size()); + two += 'x'; + } + } +} + +int main() +{ + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/1.cc index 194e09d2184..6eb37e014cc 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/1.cc @@ -18,7 +18,7 @@ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. -// 21.3.5.3 basic_string::assign +// 21.3.5.2 basic_string::append #include #include diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/2.cc new file mode 100644 index 00000000000..8af018b40f2 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/2.cc @@ -0,0 +1,67 @@ +// 2004-25-10 Paolo Carlini + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 21.3.5 string modifiers + +#include +#include + +// append(const _CharT* __s, size_type __n) +// append(const _CharT* __s) +void +test02() +{ + bool test __attribute__((unused)) = true; + + using namespace std; + + wstring one; + wstring two; + wstring three; + const wchar_t * source = L"Written in your eyes"; + + one.append(source); + VERIFY( one == L"Written in your eyes" ); + + two.append(source, 20); + VERIFY( two == L"Written in your eyes" ); + + three.append(source, 7); + VERIFY( three == L"Written" ); + + three.clear(); + three.append(source + 8, 2); + VERIFY( three == L"in" ); + + one.append(one.c_str(), 20); + VERIFY( one == L"Written in your eyesWritten in your eyes" ); + + two.append(two.c_str() + 16, 4); + VERIFY( two == L"Written in your eyeseyes" ); + + two.append(two.c_str(), 3); + VERIFY( two == L"Written in your eyeseyesWri" ); +} + +int main() +{ + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/3.cc b/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/3.cc new file mode 100644 index 00000000000..8ebaa6513ba --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/append/wchar_t/3.cc @@ -0,0 +1,56 @@ +// 2004-25-10 Paolo Carlini + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 21.3.5 string modifiers + +#include +#include + +// Upon reallocation (basic_string::reserve) we were copying from +// deallocated memory. +void +test03() +{ + bool test __attribute__((unused)) = true; + + using namespace std; + + const wchar_t * source = L"Kesto"; + + for (unsigned i = 0; i < 10; ++i) + { + wstring one(source); + wstring two(source); + for (unsigned j = 0; j < 18; ++j) + { + VERIFY( one == two ); + one.append(one); + one += L'x'; + two.append(two.c_str(), two.size()); + two += L'x'; + } + } +} + +int main() +{ + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/assign/char/3.cc b/libstdc++-v3/testsuite/21_strings/basic_string/assign/char/3.cc index 0c08fe7c72e..232a46028bd 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/assign/char/3.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/assign/char/3.cc @@ -1,6 +1,6 @@ // 2001-10-30 Benjamin Kosnik -// Copyright (C) 2001, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -21,7 +21,6 @@ // 21.3.5 string modifiers #include -#include #include // assign(const _CharT* __s, size_type __n) @@ -35,7 +34,6 @@ test03() string one; string two; - string three = two; const char * source = "Selling England by the pound"; one.assign(source); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/assign/wchar_t/3.cc b/libstdc++-v3/testsuite/21_strings/basic_string/assign/wchar_t/3.cc index 0d46ebe653d..b656d82f390 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/assign/wchar_t/3.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/assign/wchar_t/3.cc @@ -1,6 +1,6 @@ // 2001-10-30 Benjamin Kosnik -// Copyright (C) 2001, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -21,7 +21,6 @@ // 21.3.5 string modifiers #include -#include #include // assign(const _CharT* __s, size_type __n) @@ -35,7 +34,6 @@ test03() wstring one; wstring two; - wstring three = two; const wchar_t* source = L"Selling England by the pound"; one.assign(source);