Commit cf882919 by Paolo Carlini Committed by Paolo Carlini

vstring.h (__versa_string<>::operator+, [...]): Move out of line...

2005-12-04  Paolo Carlini  <pcarlini@suse.de>

	* include/ext/vstring.h (__versa_string<>::operator+, all
	versions): Move out of line...
	* include/ext/vstring.tcc (__versa_string<>::operator+): ...
	here; consistently use reserve for the benefit of sso_string_base;
	prefer push_back to single-char append when appropriate.

	* include/ext/vstring.h (__versa_string<>::push_back): Don't
	call _M_reserve, _M_mutate instead.
	(reserve): Just forward to _M_reserve.
	* include/ext/vstring.tcc (__versa_string<>::_M_reserve): Remove.
	* include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve): Also
	do the initial checks (first on length, in case __res == capacity).
	* include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve:
	Likewise; don't call _M_set_length unnecessarily.

2005-12-04  Paolo Carlini  <pcarlini@suse.de>

	* include/ext/vstring.h (__versa_string<>::_M_append): New.
	(append(const __versa_string&), append(const __versa_string&,
	size_type, size_type), append(const _CharT*, size_type),
	append(const _CharT*)): Use it.
	(append(size_type, _CharT)): Delegate to _M_replace_aux.
	(assign(const __versa_string&, size_type, size_type),
	assign(const _CharT*), replace(size_type, size_type,
	const _CharT*, size_type)): Forward to _M_replace.
	* include/ext/vstring.tcc (__versa_string<>::_M_append):
	Define, core append functionality.
	(_M_replace): Simplify, move __s == 0 case to _M_replace_aux.
	(_M_replace_aux): Reorganize, don't call _M_replace.

2005-12-04  Paolo Carlini  <pcarlini@suse.de>

	* include/ext/vstring.tcc (__versa_string<>::_M_replace):
	Perform _M_check_length at the beginning and remove it from ...
	(replace, _M_replace_dispatch, _M_replace_aux, assign): ... here.
	(assign): Now move inline.
	(resize): Don't call _M_check_length redundantly, append does.

2005-12-04  Paolo Carlini  <pcarlini@suse.de>

	* include/ext/sso_string_base.h (__sso_string_base<>::_M_get_allocator):
	Add non const version.
	* include/ext/rc_string_base.h (__rc_string_base<>::_M_get_allocator):
	Likewise.
	
	* include/ext/sso_string_base.h (__sso_string_base<>::_M_erase): Add.
	* include/ext/rc_string_base.h (__rc_string_base<>::_M_erase): Likewise.
	(_M_leak_hard): Use it.
	* include/ext/vstring.h (__versa_string<>::clear, erase, all
	versions): Use it.
	* include/ext/vstring.tcc (__versa_string<>::resize): Likewise.

	* include/ext/vstring.h (__versa_string<>::_M_replace_safe):
	Remove.
	* include/ext/vstring.h (__versa_string<>::_M_replace): New, does
	the in-place work or delegates to _M_mutate in case of reallocation.
	* include/ext/vstring.tcc (__versa_string<>::_M_replace_safe):
	Remove.
	* include/ext/vstring.tcc (__versa_string<>::_M_replace): Define.
	(assign, replace, _M_replace_dispatch, _M_replace_aux): Use it.
	* include/ext/sso_string_base.h (__sso_string_base<>::_M_mutate):
	Change to manage only reallocations.
	* include/ext/rc_string_base.h (__rc_string_base<>::_M_mutate):
	Likewise.

	* include/ext/vstring.h (__versa_string<>::insert(size_type,
	const __versa_string&), insert(size_type, const __versa_string&,
	size_type, size_type), insert(size_type, const _CharT*, size_type),
	insert(size_type, const _CharT*)): Delegate to replace.

	* include/ext/vstring.h (__versa_string<>::reserve): Move out of
	line.
	* include/ext/vstring.tcc (__versa_string<>::reserve): Do the
	checks and call _M_reserve.
	* include/ext/vstring.h (__versa_string<>::append): Call _M_reserve
	instead of reserve.
	* include/ext/vstring.tcc (__versa_string<>::append, all versions):
	Likewise.
	* include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve):
	Adjust.
	* include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve):
	Likewise.

From-SVN: r108034
parent 73433986
2005-12-04 Paolo Carlini <pcarlini@suse.de>
* include/ext/vstring.h (__versa_string<>::operator+, all
versions): Move out of line...
* include/ext/vstring.tcc (__versa_string<>::operator+): ...
here; consistently use reserve for the benefit of sso_string_base;
prefer push_back to single-char append when appropriate.
* include/ext/vstring.h (__versa_string<>::push_back): Don't
call _M_reserve, _M_mutate instead.
(reserve): Just forward to _M_reserve.
* include/ext/vstring.tcc (__versa_string<>::_M_reserve): Remove.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve): Also
do the initial checks (first on length, in case __res == capacity).
* include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve:
Likewise; don't call _M_set_length unnecessarily.
2005-12-04 Paolo Carlini <pcarlini@suse.de>
* include/ext/vstring.h (__versa_string<>::_M_append): New.
(append(const __versa_string&), append(const __versa_string&,
size_type, size_type), append(const _CharT*, size_type),
append(const _CharT*)): Use it.
(append(size_type, _CharT)): Delegate to _M_replace_aux.
(assign(const __versa_string&, size_type, size_type),
assign(const _CharT*), replace(size_type, size_type,
const _CharT*, size_type)): Forward to _M_replace.
* include/ext/vstring.tcc (__versa_string<>::_M_append):
Define, core append functionality.
(_M_replace): Simplify, move __s == 0 case to _M_replace_aux.
(_M_replace_aux): Reorganize, don't call _M_replace.
2005-12-04 Paolo Carlini <pcarlini@suse.de>
* include/ext/vstring.tcc (__versa_string<>::_M_replace):
Perform _M_check_length at the beginning and remove it from ...
(replace, _M_replace_dispatch, _M_replace_aux, assign): ... here.
(assign): Now move inline.
(resize): Don't call _M_check_length redundantly, append does.
2005-12-04 Paolo Carlini <pcarlini@suse.de>
* include/ext/sso_string_base.h (__sso_string_base<>::_M_get_allocator):
Add non const version.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_get_allocator):
Likewise.
* include/ext/sso_string_base.h (__sso_string_base<>::_M_erase): Add.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_erase): Likewise.
(_M_leak_hard): Use it.
* include/ext/vstring.h (__versa_string<>::clear, erase, all
versions): Use it.
* include/ext/vstring.tcc (__versa_string<>::resize): Likewise.
* include/ext/vstring.h (__versa_string<>::_M_replace_safe):
Remove.
* include/ext/vstring.h (__versa_string<>::_M_replace): New, does
the in-place work or delegates to _M_mutate in case of reallocation.
* include/ext/vstring.tcc (__versa_string<>::_M_replace_safe):
Remove.
* include/ext/vstring.tcc (__versa_string<>::_M_replace): Define.
(assign, replace, _M_replace_dispatch, _M_replace_aux): Use it.
* include/ext/sso_string_base.h (__sso_string_base<>::_M_mutate):
Change to manage only reallocations.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_mutate):
Likewise.
* include/ext/vstring.h (__versa_string<>::insert(size_type,
const __versa_string&), insert(size_type, const __versa_string&,
size_type, size_type), insert(size_type, const _CharT*, size_type),
insert(size_type, const _CharT*)): Delegate to replace.
* include/ext/vstring.h (__versa_string<>::reserve): Move out of
line.
* include/ext/vstring.tcc (__versa_string<>::reserve): Do the
checks and call _M_reserve.
* include/ext/vstring.h (__versa_string<>::append): Call _M_reserve
instead of reserve.
* include/ext/vstring.tcc (__versa_string<>::append, all versions):
Likewise.
* include/ext/sso_string_base.h (__sso_string_base<>::_M_reserve):
Adjust.
* include/ext/rc_string_base.h (__rc_string_base<>::_M_reserve):
Likewise.
2005-12-02 David Billinghurst (David.Billinghurst@riotinto.com) 2005-12-02 David Billinghurst (David.Billinghurst@riotinto.com)
PR testsuite/25193 PR testsuite/25193
......
...@@ -311,6 +311,10 @@ namespace __gnu_cxx ...@@ -311,6 +311,10 @@ namespace __gnu_cxx
~__rc_string_base() ~__rc_string_base()
{ _M_dispose(); } { _M_dispose(); }
allocator_type&
_M_get_allocator()
{ return _M_dataplus; }
const allocator_type& const allocator_type&
_M_get_allocator() const _M_get_allocator() const
{ return _M_dataplus; } { return _M_dataplus; }
...@@ -325,7 +329,11 @@ namespace __gnu_cxx ...@@ -325,7 +329,11 @@ namespace __gnu_cxx
_M_reserve(size_type __res); _M_reserve(size_type __res);
void void
_M_mutate(size_type __pos, size_type __len1, size_type __len2); _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
size_type __len2);
void
_M_erase(size_type __pos, size_type __n);
}; };
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
...@@ -377,8 +385,8 @@ namespace __gnu_cxx ...@@ -377,8 +385,8 @@ namespace __gnu_cxx
// NB: Need an array of char_type[__capacity], plus a terminating // NB: Need an array of char_type[__capacity], plus a terminating
// null char_type() element, plus enough for the _Rep data structure, // null char_type() element, plus enough for the _Rep data structure,
// plus sizeof(size_type) - 1 to upper round to a size multiple // plus sizeof(_Rep) - 1 to upper round to a size multiple of
// of sizeof(size_type). // sizeof(_Rep).
// Whew. Seemingly so needy, yet so elemental. // Whew. Seemingly so needy, yet so elemental.
size_type __size = ((__capacity + 1) * sizeof(_CharT) size_type __size = ((__capacity + 1) * sizeof(_CharT)
+ 2 * sizeof(_Rep) - 1); + 2 * sizeof(_Rep) - 1);
...@@ -458,7 +466,7 @@ namespace __gnu_cxx ...@@ -458,7 +466,7 @@ namespace __gnu_cxx
_M_leak_hard() _M_leak_hard()
{ {
if (_M_is_shared()) if (_M_is_shared())
_M_mutate(0, 0, 0); _M_erase(0, 0);
_M_set_leaked(); _M_set_leaked();
} }
...@@ -490,7 +498,7 @@ namespace __gnu_cxx ...@@ -490,7 +498,7 @@ namespace __gnu_cxx
{ {
while (__beg != __end) while (__beg != __end)
{ {
if (__len == __r->_M_capacity) if (__len == __r->_M_info._M_capacity)
{ {
// Allocate more space. // Allocate more space.
_Rep* __another = _Rep::_S_create(__len + 1, __len, __a); _Rep* __another = _Rep::_S_create(__len + 1, __len, __a);
...@@ -594,12 +602,12 @@ namespace __gnu_cxx ...@@ -594,12 +602,12 @@ namespace __gnu_cxx
__rc_string_base<_CharT, _Traits, _Alloc>:: __rc_string_base<_CharT, _Traits, _Alloc>::
_M_reserve(size_type __res) _M_reserve(size_type __res)
{ {
// Make sure we don't shrink below the current size.
if (__res < _M_length())
__res = _M_length();
if (__res != _M_capacity() || _M_is_shared()) if (__res != _M_capacity() || _M_is_shared())
{ {
// Make sure we don't shrink below the current size.
if (__res < _M_length())
__res = _M_length();
_CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(), _CharT* __tmp = _M_rep()->_M_clone(_M_get_allocator(),
__res - _M_length()); __res - _M_length());
_M_dispose(); _M_dispose();
...@@ -610,13 +618,35 @@ namespace __gnu_cxx ...@@ -610,13 +618,35 @@ namespace __gnu_cxx
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
void void
__rc_string_base<_CharT, _Traits, _Alloc>:: __rc_string_base<_CharT, _Traits, _Alloc>::
_M_mutate(size_type __pos, size_type __len1, size_type __len2) _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
size_type __len2)
{ {
const size_type __old_size = _M_length(); const size_type __how_much = _M_length() - __pos - __len1;
const size_type __new_size = __old_size + __len2 - __len1;
const size_type __how_much = __old_size - __pos - __len1; _Rep* __r = _Rep::_S_create(_M_length() + __len2 - __len1,
_M_capacity(), _M_get_allocator());
if (__new_size > _M_capacity() || _M_is_shared()) if (__pos)
_S_copy(__r->_M_refdata(), _M_data(), __pos);
if (__s && __len2)
_S_copy(__r->_M_refdata() + __pos, __s, __len2);
if (__how_much)
_S_copy(__r->_M_refdata() + __pos + __len2,
_M_data() + __pos + __len1, __how_much);
_M_dispose();
_M_data(__r->_M_refdata());
}
template<typename _CharT, typename _Traits, typename _Alloc>
void
__rc_string_base<_CharT, _Traits, _Alloc>::
_M_erase(size_type __pos, size_type __n)
{
const size_type __new_size = _M_length() - __n;
const size_type __how_much = _M_length() - __pos - __n;
if (_M_is_shared())
{ {
// Must reallocate. // Must reallocate.
_Rep* __r = _Rep::_S_create(__new_size, _M_capacity(), _Rep* __r = _Rep::_S_create(__new_size, _M_capacity(),
...@@ -625,19 +655,20 @@ namespace __gnu_cxx ...@@ -625,19 +655,20 @@ namespace __gnu_cxx
if (__pos) if (__pos)
_S_copy(__r->_M_refdata(), _M_data(), __pos); _S_copy(__r->_M_refdata(), _M_data(), __pos);
if (__how_much) if (__how_much)
_S_copy(__r->_M_refdata() + __pos + __len2, _S_copy(__r->_M_refdata() + __pos,
_M_data() + __pos + __len1, __how_much); _M_data() + __pos + __n, __how_much);
_M_dispose(); _M_dispose();
_M_data(__r->_M_refdata()); _M_data(__r->_M_refdata());
} }
else if (__how_much && __len1 != __len2) else if (__how_much && __n)
{ {
// Work in-place. // Work in-place.
_S_move(_M_data() + __pos + __len2, _S_move(_M_data() + __pos,
_M_data() + __pos + __len1, __how_much); _M_data() + __pos + __n, __how_much);
} }
_M_rep()->_M_set_length(__new_size);
_M_rep()->_M_set_length(__new_size);
} }
} // namespace __gnu_cxx } // namespace __gnu_cxx
......
...@@ -202,6 +202,10 @@ namespace __gnu_cxx ...@@ -202,6 +202,10 @@ namespace __gnu_cxx
~__sso_string_base() ~__sso_string_base()
{ _M_dispose(); } { _M_dispose(); }
allocator_type&
_M_get_allocator()
{ return _M_dataplus; }
const allocator_type& const allocator_type&
_M_get_allocator() const _M_get_allocator() const
{ return _M_dataplus; } { return _M_dataplus; }
...@@ -216,7 +220,11 @@ namespace __gnu_cxx ...@@ -216,7 +220,11 @@ namespace __gnu_cxx
_M_reserve(size_type __res); _M_reserve(size_type __res);
void void
_M_mutate(size_type __pos, size_type __len1, size_type __len2); _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
size_type __len2);
void
_M_erase(size_type __pos, size_type __n);
}; };
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
...@@ -471,19 +479,18 @@ namespace __gnu_cxx ...@@ -471,19 +479,18 @@ namespace __gnu_cxx
__sso_string_base<_CharT, _Traits, _Alloc>:: __sso_string_base<_CharT, _Traits, _Alloc>::
_M_reserve(size_type __res) _M_reserve(size_type __res)
{ {
// Make sure we don't shrink below the current size.
if (__res < _M_length())
__res = _M_length();
const size_type __capacity = _M_capacity(); const size_type __capacity = _M_capacity();
if (__res != __capacity) if (__res != __capacity)
{ {
// Make sure we don't shrink below the current size.
if (__res < _M_length())
__res = _M_length();
if (__res > __capacity if (__res > __capacity
|| __res > size_type(_S_local_capacity)) || __res > size_type(_S_local_capacity))
{ {
_CharT* __tmp = _M_create(__res, __capacity); _CharT* __tmp = _M_create(__res, __capacity);
if (_M_length()) _S_copy(__tmp, _M_data(), _M_length() + 1);
_S_copy(__tmp, _M_data(), _M_length());
_M_dispose(); _M_dispose();
_M_data(__tmp); _M_data(__tmp);
_M_capacity(__res); _M_capacity(__res);
...@@ -491,49 +498,49 @@ namespace __gnu_cxx ...@@ -491,49 +498,49 @@ namespace __gnu_cxx
else if (!_M_is_local()) else if (!_M_is_local())
{ {
const size_type __tmp_capacity = _M_allocated_capacity; const size_type __tmp_capacity = _M_allocated_capacity;
if (_M_length()) _S_copy(_M_local_data, _M_data(), _M_length() + 1);
_S_copy(_M_local_data, _M_data(), _M_length());
_M_destroy(__tmp_capacity + 1); _M_destroy(__tmp_capacity + 1);
_M_data(_M_local_data); _M_data(_M_local_data);
} }
_M_set_length(_M_length());
} }
} }
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
void void
__sso_string_base<_CharT, _Traits, _Alloc>:: __sso_string_base<_CharT, _Traits, _Alloc>::
_M_mutate(size_type __pos, size_type __len1, size_type __len2) _M_mutate(size_type __pos, size_type __len1, const _CharT* __s,
const size_type __len2)
{ {
const size_type __old_size = _M_length(); const size_type __how_much = _M_length() - __pos - __len1;
const size_type __new_size = __old_size + __len2 - __len1;
const size_type __how_much = __old_size - __pos - __len1;
if (__new_size > _M_capacity()) size_type __new_capacity = _M_length() + __len2 - __len1;
{ _CharT* __r = _M_create(__new_capacity, _M_capacity());
// Must reallocate.
size_type __new_capacity = __new_size; if (__pos)
_CharT* __r = _M_create(__new_capacity, _M_capacity()); _S_copy(__r, _M_data(), __pos);
if (__s && __len2)
_S_copy(__r + __pos, __s, __len2);
if (__how_much)
_S_copy(__r + __pos + __len2,
_M_data() + __pos + __len1, __how_much);
_M_dispose();
_M_data(__r);
_M_capacity(__new_capacity);
}
if (__pos) template<typename _CharT, typename _Traits, typename _Alloc>
_S_copy(__r, _M_data(), __pos); void
if (__how_much) __sso_string_base<_CharT, _Traits, _Alloc>::
_S_copy(__r + __pos + __len2, _M_erase(size_type __pos, size_type __n)
_M_data() + __pos + __len1, __how_much); {
const size_type __how_much = _M_length() - __pos - __n;
_M_dispose(); if (__how_much && __n)
_M_data(__r); _S_move(_M_data() + __pos, _M_data() + __pos + __n,
_M_capacity(__new_capacity); __how_much);
}
else if (__how_much && __len1 != __len2)
{
// Work in-place.
_S_move(_M_data() + __pos + __len2,
_M_data() + __pos + __len1, __how_much);
}
_M_set_length(__new_size); _M_set_length(_M_length() - __n);
} }
} // namespace __gnu_cxx } // namespace __gnu_cxx
......
...@@ -402,14 +402,14 @@ namespace __gnu_cxx ...@@ -402,14 +402,14 @@ namespace __gnu_cxx
*/ */
void void
reserve(size_type __res_arg = 0) reserve(size_type __res_arg = 0)
{ this->_M_reserve(__res_arg); } { this->_M_reserve(__res_arg); }
/** /**
* Erases the string, making it empty. * Erases the string, making it empty.
*/ */
void void
clear() clear()
{ this->_M_mutate(0, this->size(), 0); } { this->_M_erase(size_type(0), this->size()); }
/** /**
* Returns true if the %string is empty. Equivalent to *this == "". * Returns true if the %string is empty. Equivalent to *this == "".
...@@ -529,7 +529,8 @@ namespace __gnu_cxx ...@@ -529,7 +529,8 @@ namespace __gnu_cxx
* @return Reference to this string. * @return Reference to this string.
*/ */
__versa_string& __versa_string&
append(const __versa_string& __str); append(const __versa_string& __str)
{ return _M_append(__str._M_data(), __str.size()); }
/** /**
* @brief Append a substring. * @brief Append a substring.
...@@ -544,7 +545,10 @@ namespace __gnu_cxx ...@@ -544,7 +545,10 @@ namespace __gnu_cxx
* characters in @a str, the remainder of @a str is appended. * characters in @a str, the remainder of @a str is appended.
*/ */
__versa_string& __versa_string&
append(const __versa_string& __str, size_type __pos, size_type __n); append(const __versa_string& __str, size_type __pos, size_type __n)
{ return _M_append(__str._M_data()
+ __str._M_check(__pos, "__versa_string::append"),
__str._M_limit(__pos, __n)); }
/** /**
* @brief Append a C substring. * @brief Append a C substring.
...@@ -553,7 +557,12 @@ namespace __gnu_cxx ...@@ -553,7 +557,12 @@ namespace __gnu_cxx
* @return Reference to this string. * @return Reference to this string.
*/ */
__versa_string& __versa_string&
append(const _CharT* __s, size_type __n); append(const _CharT* __s, size_type __n)
{
__glibcxx_requires_string_len(__s, __n);
_M_check_length(size_type(0), __n, "__versa_string::append");
return _M_append(__s, __n);
}
/** /**
* @brief Append a C string. * @brief Append a C string.
...@@ -564,7 +573,9 @@ namespace __gnu_cxx ...@@ -564,7 +573,9 @@ namespace __gnu_cxx
append(const _CharT* __s) append(const _CharT* __s)
{ {
__glibcxx_requires_string(__s); __glibcxx_requires_string(__s);
return this->append(__s, traits_type::length(__s)); const size_type __n = traits_type::length(__s);
_M_check_length(size_type(0), __n, "__versa_string::append");
return _M_append(__s, __n);
} }
/** /**
...@@ -576,7 +587,8 @@ namespace __gnu_cxx ...@@ -576,7 +587,8 @@ namespace __gnu_cxx
* Appends n copies of c to this string. * Appends n copies of c to this string.
*/ */
__versa_string& __versa_string&
append(size_type __n, _CharT __c); append(size_type __n, _CharT __c)
{ return _M_replace_aux(this->size(), size_type(0), __n, __c); }
/** /**
* @brief Append a range of characters. * @brief Append a range of characters.
...@@ -598,11 +610,11 @@ namespace __gnu_cxx ...@@ -598,11 +610,11 @@ namespace __gnu_cxx
void void
push_back(_CharT __c) push_back(_CharT __c)
{ {
const size_type __len = 1 + this->size(); const size_type __size = this->size();
if (__len > this->capacity() || this->_M_is_shared()) if (__size + 1 > this->capacity() || this->_M_is_shared())
this->reserve(__len); this->_M_mutate(__size, size_type(0), 0, size_type(1));
traits_type::assign(this->_M_data()[this->size()], __c); traits_type::assign(this->_M_data()[__size], __c);
this->_M_set_length(__len); this->_M_set_length(__size + 1);
} }
/** /**
...@@ -631,9 +643,9 @@ namespace __gnu_cxx ...@@ -631,9 +643,9 @@ namespace __gnu_cxx
*/ */
__versa_string& __versa_string&
assign(const __versa_string& __str, size_type __pos, size_type __n) assign(const __versa_string& __str, size_type __pos, size_type __n)
{ return this->assign(__str._M_data() { return _M_replace(size_type(0), this->size(), __str._M_data()
+ __str._M_check(__pos, "__versa_string::assign"), + __str._M_check(__pos, "__versa_string::assign"),
__str._M_limit(__pos, __n)); } __str._M_limit(__pos, __n)); }
/** /**
* @brief Set value to a C substring. * @brief Set value to a C substring.
...@@ -646,7 +658,11 @@ namespace __gnu_cxx ...@@ -646,7 +658,11 @@ namespace __gnu_cxx
* available characters in @a s, the remainder of @a s is used. * available characters in @a s, the remainder of @a s is used.
*/ */
__versa_string& __versa_string&
assign(const _CharT* __s, size_type __n); assign(const _CharT* __s, size_type __n)
{
__glibcxx_requires_string_len(__s, __n);
return _M_replace(size_type(0), this->size(), __s, __n);
}
/** /**
* @brief Set value to contents of a C string. * @brief Set value to contents of a C string.
...@@ -661,7 +677,8 @@ namespace __gnu_cxx ...@@ -661,7 +677,8 @@ namespace __gnu_cxx
assign(const _CharT* __s) assign(const _CharT* __s)
{ {
__glibcxx_requires_string(__s); __glibcxx_requires_string(__s);
return this->assign(__s, traits_type::length(__s)); return _M_replace(size_type(0), this->size(), __s,
traits_type::length(__s));
} }
/** /**
...@@ -735,7 +752,8 @@ namespace __gnu_cxx ...@@ -735,7 +752,8 @@ namespace __gnu_cxx
*/ */
__versa_string& __versa_string&
insert(size_type __pos1, const __versa_string& __str) insert(size_type __pos1, const __versa_string& __str)
{ return this->insert(__pos1, __str, size_type(0), __str.size()); } { return this->replace(__pos1, size_type(0),
__str._M_data(), __str.size()); }
/** /**
* @brief Insert a substring. * @brief Insert a substring.
...@@ -758,9 +776,9 @@ namespace __gnu_cxx ...@@ -758,9 +776,9 @@ namespace __gnu_cxx
__versa_string& __versa_string&
insert(size_type __pos1, const __versa_string& __str, insert(size_type __pos1, const __versa_string& __str,
size_type __pos2, size_type __n) size_type __pos2, size_type __n)
{ return this->insert(__pos1, __str._M_data() { return this->replace(__pos1, size_type(0), __str._M_data()
+ __str._M_check(__pos2, "__versa_string::insert"), + __str._M_check(__pos2, "__versa_string::insert"),
__str._M_limit(__pos2, __n)); } __str._M_limit(__pos2, __n)); }
/** /**
* @brief Insert a C substring. * @brief Insert a C substring.
...@@ -779,7 +797,8 @@ namespace __gnu_cxx ...@@ -779,7 +797,8 @@ namespace __gnu_cxx
* thrown. * thrown.
*/ */
__versa_string& __versa_string&
insert(size_type __pos, const _CharT* __s, size_type __n); insert(size_type __pos, const _CharT* __s, size_type __n)
{ return this->replace(__pos, size_type(0), __s, __n); }
/** /**
* @brief Insert a C string. * @brief Insert a C string.
...@@ -800,7 +819,8 @@ namespace __gnu_cxx ...@@ -800,7 +819,8 @@ namespace __gnu_cxx
insert(size_type __pos, const _CharT* __s) insert(size_type __pos, const _CharT* __s)
{ {
__glibcxx_requires_string(__s); __glibcxx_requires_string(__s);
return this->insert(__pos, __s, traits_type::length(__s)); return this->replace(__pos, size_type(0), __s,
traits_type::length(__s));
} }
/** /**
...@@ -843,7 +863,7 @@ namespace __gnu_cxx ...@@ -843,7 +863,7 @@ namespace __gnu_cxx
const size_type __pos = __p - _M_ibegin(); const size_type __pos = __p - _M_ibegin();
_M_replace_aux(__pos, size_type(0), size_type(1), __c); _M_replace_aux(__pos, size_type(0), size_type(1), __c);
this->_M_set_leaked(); this->_M_set_leaked();
return _M_ibegin() + __pos; return iterator(this->_M_data() + __pos);
} }
/** /**
...@@ -863,8 +883,8 @@ namespace __gnu_cxx ...@@ -863,8 +883,8 @@ namespace __gnu_cxx
__versa_string& __versa_string&
erase(size_type __pos = 0, size_type __n = npos) erase(size_type __pos = 0, size_type __n = npos)
{ {
this->_M_mutate(_M_check(__pos, "__versa_string::erase"), this->_M_erase(_M_check(__pos, "__versa_string::erase"),
_M_limit(__pos, __n), size_type(0)); _M_limit(__pos, __n));
return *this; return *this;
} }
...@@ -882,9 +902,9 @@ namespace __gnu_cxx ...@@ -882,9 +902,9 @@ namespace __gnu_cxx
_GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin() _GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
&& __position < _M_iend()); && __position < _M_iend());
const size_type __pos = __position - _M_ibegin(); const size_type __pos = __position - _M_ibegin();
this->_M_mutate(__pos, size_type(1), size_type(0)); this->_M_erase(__pos, size_type(1));
this->_M_set_leaked(); this->_M_set_leaked();
return _M_ibegin() + __pos; return iterator(this->_M_data() + __pos);
} }
/** /**
...@@ -902,9 +922,9 @@ namespace __gnu_cxx ...@@ -902,9 +922,9 @@ namespace __gnu_cxx
_GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last _GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
&& __last <= _M_iend()); && __last <= _M_iend());
const size_type __pos = __first - _M_ibegin(); const size_type __pos = __first - _M_ibegin();
this->_M_mutate(__pos, __last - __first, size_type(0)); this->_M_erase(__pos, __last - __first);
this->_M_set_leaked(); this->_M_set_leaked();
return _M_ibegin() + __pos; return iterator(this->_M_data() + __pos);
} }
/** /**
...@@ -974,7 +994,12 @@ namespace __gnu_cxx ...@@ -974,7 +994,12 @@ namespace __gnu_cxx
*/ */
__versa_string& __versa_string&
replace(size_type __pos, size_type __n1, const _CharT* __s, replace(size_type __pos, size_type __n1, const _CharT* __s,
size_type __n2); size_type __n2)
{
__glibcxx_requires_string_len(__s, __n2);
return _M_replace(_M_check(__pos, "__versa_string::replace"),
_M_limit(__pos, __n1), __s, __n2);
}
/** /**
* @brief Replace characters with value of a C string. * @brief Replace characters with value of a C string.
...@@ -1187,8 +1212,11 @@ namespace __gnu_cxx ...@@ -1187,8 +1212,11 @@ namespace __gnu_cxx
_CharT __c); _CharT __c);
__versa_string& __versa_string&
_M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
size_type __n2); const size_type __len2);
__versa_string&
_M_append(const _CharT* __s, size_type __n);
public: public:
...@@ -1771,12 +1799,7 @@ namespace __gnu_cxx ...@@ -1771,12 +1799,7 @@ namespace __gnu_cxx
template <typename, typename, typename> class _Base> template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base> __versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs);
{
__versa_string<_CharT, _Traits, _Alloc, _Base> __str(__lhs);
__str.append(__rhs);
return __str;
}
/** /**
* @brief Concatenate C string and string. * @brief Concatenate C string and string.
...@@ -1810,14 +1833,9 @@ namespace __gnu_cxx ...@@ -1810,14 +1833,9 @@ namespace __gnu_cxx
*/ */
template<typename _CharT, typename _Traits, typename _Alloc, template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base> template <typename, typename, typename> class _Base>
inline __versa_string<_CharT, _Traits, _Alloc, _Base> __versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
const _CharT* __rhs) const _CharT* __rhs);
{
__versa_string<_CharT, _Traits, _Alloc, _Base> __str(__lhs);
__str.append(__rhs);
return __str;
}
/** /**
* @brief Concatenate string and character. * @brief Concatenate string and character.
...@@ -1827,17 +1845,9 @@ namespace __gnu_cxx ...@@ -1827,17 +1845,9 @@ namespace __gnu_cxx
*/ */
template<typename _CharT, typename _Traits, typename _Alloc, template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base> template <typename, typename, typename> class _Base>
inline __versa_string<_CharT, _Traits, _Alloc, _Base> __versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs, operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
_CharT __rhs) _CharT __rhs);
{
typedef __versa_string<_CharT, _Traits, _Alloc, _Base>
__string_type;
typedef typename __string_type::size_type __size_type;
__string_type __str(__lhs);
__str.append(__size_type(1), __rhs);
return __str;
}
// operator == // operator ==
/** /**
......
...@@ -47,192 +47,37 @@ namespace __gnu_cxx ...@@ -47,192 +47,37 @@ namespace __gnu_cxx
template<typename _CharT, typename _Traits, typename _Alloc, template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base> template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>& void
__versa_string<_CharT, _Traits, _Alloc, _Base>::
assign(const _CharT* __s, size_type __n)
{
__glibcxx_requires_string_len(__s, __n);
_M_check_length(this->size(), __n, "__versa_string::assign");
if (_M_disjunct(__s) || this->_M_is_shared())
return _M_replace_safe(size_type(0), this->size(), __s, __n);
else
{
// Work in-place.
const size_type __pos = __s - this->_M_data();
if (__pos >= __n)
this->_S_copy(this->_M_data(), __s, __n);
else if (__pos)
this->_S_move(this->_M_data(), __s, __n);
this->_M_set_length(__n);
return *this;
}
}
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>&
__versa_string<_CharT, _Traits, _Alloc, _Base>:: __versa_string<_CharT, _Traits, _Alloc, _Base>::
append(size_type __n, _CharT __c) resize(size_type __n, _CharT __c)
{ {
if (__n) const size_type __size = this->size();
{ if (__size < __n)
_M_check_length(size_type(0), __n, "__versa_string::append"); this->append(__n - __size, __c);
const size_type __len = __n + this->size(); else if (__n < __size)
if (__len > this->capacity() || this->_M_is_shared()) this->_M_erase(__n, __size - __n);
this->reserve(__len);
this->_S_assign(this->_M_data() + this->size(), __n, __c);
this->_M_set_length(__len);
}
return *this;
} }
template<typename _CharT, typename _Traits, typename _Alloc, template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base> template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>& __versa_string<_CharT, _Traits, _Alloc, _Base>&
__versa_string<_CharT, _Traits, _Alloc, _Base>:: __versa_string<_CharT, _Traits, _Alloc, _Base>::
append(const _CharT* __s, size_type __n) _M_append(const _CharT* __s, size_type __n)
{ {
__glibcxx_requires_string_len(__s, __n); const size_type __len = __n + this->size();
if (__n)
{
_M_check_length(size_type(0), __n, "__versa_string::append");
const size_type __len = __n + this->size();
if (__len > this->capacity() || this->_M_is_shared())
{
if (_M_disjunct(__s))
this->reserve(__len);
else
{
const size_type __off = __s - this->_M_data();
this->reserve(__len);
__s = this->_M_data() + __off;
}
}
this->_S_copy(this->_M_data() + this->size(), __s, __n);
this->_M_set_length(__len);
}
return *this;
}
template<typename _CharT, typename _Traits, typename _Alloc, if (__len <= this->capacity() && !this->_M_is_shared())
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>&
__versa_string<_CharT, _Traits, _Alloc, _Base>::
append(const __versa_string& __str)
{
const size_type __size = __str.size();
if (__size)
{ {
const size_type __len = __size + this->size(); if (__n)
if (__len > this->capacity() || this->_M_is_shared()) this->_S_copy(this->_M_data() + this->size(), __s, __n);
this->reserve(__len);
this->_S_copy(this->_M_data() + this->size(), __str._M_data(),
__size);
this->_M_set_length(__len);
} }
return *this; else
} this->_M_mutate(this->size(), size_type(0), __s, __n);
template<typename _CharT, typename _Traits, typename _Alloc, this->_M_set_length(__len);
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>&
__versa_string<_CharT, _Traits, _Alloc, _Base>::
append(const __versa_string& __str, size_type __pos, size_type __n)
{
__str._M_check(__pos, "__versa_string::append");
__n = __str._M_limit(__pos, __n);
if (__n)
{
const size_type __len = __n + this->size();
if (__len > this->capacity() || this->_M_is_shared())
this->reserve(__len);
this->_S_copy(this->_M_data() + this->size(),
__str._M_data() + __pos, __n);
this->_M_set_length(__len);
}
return *this; return *this;
} }
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>&
__versa_string<_CharT, _Traits, _Alloc, _Base>::
insert(size_type __pos, const _CharT* __s, size_type __n)
{
__glibcxx_requires_string_len(__s, __n);
_M_check(__pos, "__versa_string::insert");
_M_check_length(size_type(0), __n, "__versa_string::insert");
if (_M_disjunct(__s) || this->_M_is_shared())
return _M_replace_safe(__pos, size_type(0), __s, __n);
else
{
// Work in-place.
const size_type __off = __s - this->_M_data();
this->_M_mutate(__pos, 0, __n);
__s = this->_M_data() + __off;
_CharT* __p = this->_M_data() + __pos;
if (__s + __n <= __p)
this->_S_copy(__p, __s, __n);
else if (__s >= __p)
this->_S_copy(__p, __s + __n, __n);
else
{
const size_type __nleft = __p - __s;
this->_S_copy(__p, __s, __nleft);
this->_S_copy(__p + __nleft, __p + __n, __n - __nleft);
}
return *this;
}
}
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>&
__versa_string<_CharT, _Traits, _Alloc, _Base>::
replace(size_type __pos, size_type __n1, const _CharT* __s,
size_type __n2)
{
__glibcxx_requires_string_len(__s, __n2);
_M_check(__pos, "__versa_string::replace");
__n1 = _M_limit(__pos, __n1);
_M_check_length(__n1, __n2, "__versa_string::replace");
bool __left;
if (_M_disjunct(__s) || this->_M_is_shared())
return _M_replace_safe(__pos, __n1, __s, __n2);
else if ((__left = __s + __n2 <= this->_M_data() + __pos)
|| this->_M_data() + __pos + __n1 <= __s)
{
// Work in-place: non-overlapping case.
size_type __off = __s - this->_M_data();
__left ? __off : (__off += __n2 - __n1);
this->_M_mutate(__pos, __n1, __n2);
this->_S_copy(this->_M_data() + __pos,
this->_M_data() + __off, __n2);
return *this;
}
else
{
// Todo: overlapping case.
const __versa_string __tmp(__s, __n2);
return _M_replace_safe(__pos, __n1, __tmp._M_data(), __n2);
}
}
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
void
__versa_string<_CharT, _Traits, _Alloc, _Base>::
resize(size_type __n, _CharT __c)
{
const size_type __size = this->size();
_M_check_length(__size, __n, "__versa_string::resize");
if (__size < __n)
this->append(__n - __size, __c);
else if (__n < __size)
this->erase(__n);
// else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
}
template<typename _CharT, typename _Traits, typename _Alloc, template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base> template <typename, typename, typename> class _Base>
template<typename _InputIterator> template<typename _InputIterator>
...@@ -243,10 +88,8 @@ namespace __gnu_cxx ...@@ -243,10 +88,8 @@ namespace __gnu_cxx
{ {
const __versa_string __s(__k1, __k2); const __versa_string __s(__k1, __k2);
const size_type __n1 = __i2 - __i1; const size_type __n1 = __i2 - __i1;
_M_check_length(__n1, __s.size(), return _M_replace(__i1 - _M_ibegin(), __n1, __s._M_data(),
"__versa_string::_M_replace_dispatch"); __s.size());
return _M_replace_safe(__i1 - _M_ibegin(), __n1, __s._M_data(),
__s.size());
} }
template<typename _CharT, typename _Traits, typename _Alloc, template<typename _CharT, typename _Traits, typename _Alloc,
...@@ -257,9 +100,25 @@ namespace __gnu_cxx ...@@ -257,9 +100,25 @@ namespace __gnu_cxx
_CharT __c) _CharT __c)
{ {
_M_check_length(__n1, __n2, "__versa_string::_M_replace_aux"); _M_check_length(__n1, __n2, "__versa_string::_M_replace_aux");
this->_M_mutate(__pos1, __n1, __n2);
const size_type __old_size = this->size();
const size_type __new_size = __old_size + __n2 - __n1;
if (__new_size <= this->capacity() && !this->_M_is_shared())
{
_CharT* __p = this->_M_data() + __pos1;
const size_type __how_much = __old_size - __pos1 - __n1;
if (__how_much && __n1 != __n2)
this->_S_move(__p + __n2, __p + __n1, __how_much);
}
else
this->_M_mutate(__pos1, __n1, 0, __n2);
if (__n2) if (__n2)
this->_S_assign(this->_M_data() + __pos1, __n2, __c); this->_S_assign(this->_M_data() + __pos1, __n2, __c);
this->_M_set_length(__new_size);
return *this; return *this;
} }
...@@ -267,23 +126,77 @@ namespace __gnu_cxx ...@@ -267,23 +126,77 @@ namespace __gnu_cxx
template <typename, typename, typename> class _Base> template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>& __versa_string<_CharT, _Traits, _Alloc, _Base>&
__versa_string<_CharT, _Traits, _Alloc, _Base>:: __versa_string<_CharT, _Traits, _Alloc, _Base>::
_M_replace_safe(size_type __pos1, size_type __n1, const _CharT* __s, _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
size_type __n2) const size_type __len2)
{ {
this->_M_mutate(__pos1, __n1, __n2); _M_check_length(__len1, __len2, "__versa_string::_M_replace");
if (__n2)
this->_S_copy(this->_M_data() + __pos1, __s, __n2); const size_type __old_size = this->size();
const size_type __new_size = __old_size + __len2 - __len1;
if (__new_size <= this->capacity() && !this->_M_is_shared())
{
_CharT* __p = this->_M_data() + __pos;
const size_type __how_much = __old_size - __pos - __len1;
if (_M_disjunct(__s))
{
if (__how_much && __len1 != __len2)
this->_S_move(__p + __len2, __p + __len1, __how_much);
if (__len2)
this->_S_copy(__p, __s, __len2);
}
else
{
// Work in-place.
if (__len2 && __len2 <= __len1)
this->_S_move(__p, __s, __len2);
if (__how_much && __len1 != __len2)
this->_S_move(__p + __len2, __p + __len1, __how_much);
if (__len2 > __len1)
{
if (__s + __len2 <= __p + __len1)
this->_S_move(__p, __s, __len2);
else if (__s >= __p + __len1)
this->_S_copy(__p, __s + __len2 - __len1, __len2);
else
{
const size_type __nleft = (__p + __len1) - __s;
this->_S_move(__p, __s, __nleft);
this->_S_copy(__p + __nleft, __p + __len2,
__len2 - __nleft);
}
}
}
}
else
this->_M_mutate(__pos, __len1, __s, __len2);
this->_M_set_length(__new_size);
return *this; return *this;
} }
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
{
__versa_string<_CharT, _Traits, _Alloc, _Base> __str;
__str.reserve(__lhs.size() + __rhs.size());
__str.append(__lhs);
__str.append(__rhs);
return __str;
}
template<typename _CharT, typename _Traits, typename _Alloc, template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base> template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base> __versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const _CharT* __lhs, operator+(const _CharT* __lhs,
const __versa_string<_CharT, _Traits, _Alloc>& __rhs) const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
{ {
__glibcxx_requires_string(__lhs); __glibcxx_requires_string(__lhs);
typedef __versa_string<_CharT, _Traits, _Alloc> __string_type; typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
typedef typename __string_type::size_type __size_type; typedef typename __string_type::size_type __size_type;
const __size_type __len = _Traits::length(__lhs); const __size_type __len = _Traits::length(__lhs);
__string_type __str; __string_type __str;
...@@ -299,13 +212,40 @@ namespace __gnu_cxx ...@@ -299,13 +212,40 @@ namespace __gnu_cxx
operator+(_CharT __lhs, operator+(_CharT __lhs,
const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs) const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
{ {
typedef __versa_string<_CharT, _Traits, _Alloc> __string_type; __versa_string<_CharT, _Traits, _Alloc, _Base> __str;
__str.reserve(__rhs.size() + 1);
__str.push_back(__lhs);
__str.append(__rhs);
return __str;
}
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
const _CharT* __rhs)
{
__glibcxx_requires_string(__rhs);
typedef __versa_string<_CharT, _Traits, _Alloc, _Base> __string_type;
typedef typename __string_type::size_type __size_type; typedef typename __string_type::size_type __size_type;
const __size_type __len = _Traits::length(__rhs);
__string_type __str; __string_type __str;
const __size_type __len = __rhs.size(); __str.reserve(__lhs.size() + __len);
__str.reserve(__len + 1); __str.append(__lhs);
__str.append(__size_type(1), __lhs); __str.append(__rhs, __len);
__str.append(__rhs); return __str;
}
template<typename _CharT, typename _Traits, typename _Alloc,
template <typename, typename, typename> class _Base>
__versa_string<_CharT, _Traits, _Alloc, _Base>
operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
_CharT __rhs)
{
__versa_string<_CharT, _Traits, _Alloc, _Base> __str;
__str.reserve(__lhs.size() + 1);
__str.append(__lhs);
__str.push_back(__rhs);
return __str; return __str;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment