Commit e03a6fb7 by Paolo Carlini Committed by Paolo Carlini

basic_string.h (_M_check): Change to return a checked __pos and take an…

basic_string.h (_M_check): Change to return a checked __pos and take an additional const char* argument.

2004-01-21  Paolo Carlini  <pcarlini@suse.de>

	* include/bits/basic_string.h (_M_check): Change to return
	a checked __pos and take an additional const char* argument.
	(_M_fold): Rename to _M_limit, change to return a size_type,
	corresponding to the __off limited to the actual length.
	(insert(size_type, size_type, _CharT)): Update call, call
	replace.
	(insert(iterator, _CharT)): Call replace(iterator, iterator,
	size_type, _CharT) instead.
	(erase(size_type, size_type)): Update calls.
	(replace(size_type, size_type, size_type, _CharT)): Ditto.
	(substr(size_type, size_type)): Use _M_check.
	* include/bits/basic_string.tcc (basic_string(const basic_string&,
	size_type, size_type)): Update calls.
	(basic_string(const basic_string&, size_type, size_type,
	const _Alloc&)): Ditto.
	(assign(const basic_string&, size_type, size_type)): Use the
	new _M_check and _M_limit.
	(insert(size_type, const basic_string&, size_type, size_type):
	Ditto.
	(insert(size_type, const _CharT*, size_type)): Ditto.
	(replace(size_type, size_type, const _CharT*, size_type): Ditto.
	(replace(size_type, size_type, const basic_string&,
	size_type, size_type)): Ditto.
	(append(const basic_string&)): Ditto.
	(append(const basic_string&, size_type, size_type)): Ditto.
	(copy(_CharT*, size_type, size_type)): Ditto.
	(compare(size_type, size_type, const basic_string&)): Ditto.
	(compare(size_type, size_type, const basic_string&,size_type,
	size_type)): Ditto.
	(compare(size_type, size_type, const _CharT*)): Ditto.
	(compare(size_type, size_type, const _CharT*, size_type)): Ditto.

From-SVN: r76274
parent adc04486
2004-01-21 Paolo Carlini <pcarlini@suse.de>
* include/bits/basic_string.h (_M_check): Change to return
a checked __pos and take an additional const char* argument.
(_M_fold): Rename to _M_limit, change to return a size_type,
corresponding to the __off limited to the actual length.
(insert(size_type, size_type, _CharT)): Update call, call
replace.
(insert(iterator, _CharT)): Call replace(iterator, iterator,
size_type, _CharT) instead.
(erase(size_type, size_type)): Update calls.
(replace(size_type, size_type, size_type, _CharT)): Ditto.
(substr(size_type, size_type)): Use _M_check.
* include/bits/basic_string.tcc (basic_string(const basic_string&,
size_type, size_type)): Update calls.
(basic_string(const basic_string&, size_type, size_type,
const _Alloc&)): Ditto.
(assign(const basic_string&, size_type, size_type)): Use the
new _M_check and _M_limit.
(insert(size_type, const basic_string&, size_type, size_type):
Ditto.
(insert(size_type, const _CharT*, size_type)): Ditto.
(replace(size_type, size_type, const _CharT*, size_type): Ditto.
(replace(size_type, size_type, const basic_string&,
size_type, size_type)): Ditto.
(append(const basic_string&)): Ditto.
(append(const basic_string&, size_type, size_type)): Ditto.
(copy(_CharT*, size_type, size_type)): Ditto.
(compare(size_type, size_type, const basic_string&)): Ditto.
(compare(size_type, size_type, const basic_string&,size_type,
size_type)): Ditto.
(compare(size_type, size_type, const _CharT*)): Ditto.
(compare(size_type, size_type, const _CharT*, size_type)): Ditto.
2004-01-19 Stefan Olsson <stefan@snon.net> 2004-01-19 Stefan Olsson <stefan@snon.net>
* include/ext/mt_allocator.h: If a thread, when it dies, still has * include/ext/mt_allocator.h: If a thread, when it dies, still has
......
...@@ -283,21 +283,20 @@ namespace std ...@@ -283,21 +283,20 @@ namespace std
_M_leak_hard(); _M_leak_hard();
} }
iterator size_type
_M_check(size_type __pos) const _M_check(size_type __pos, const char* __s) const
{ {
if (__pos > this->size()) if (__pos > this->size())
__throw_out_of_range(__N("basic_string::_M_check")); __throw_out_of_range(__N(__s));
return _M_ibegin() + __pos; return __pos;
} }
// NB: _M_fold doesn't check for a bad __pos1 value. // NB: _M_limit doesn't check for a bad __pos value.
iterator size_type
_M_fold(size_type __pos, size_type __off) const _M_limit(size_type __pos, size_type __off) const
{ {
const bool __testoff = __off < this->size() - __pos; const bool __testoff = __off < this->size() - __pos;
const size_type __newoff = __testoff ? __off : this->size() - __pos; return __testoff ? __off : this->size() - __pos;
return (_M_ibegin() + __pos + __newoff);
} }
// _S_copy_chars is a separate template to permit specialization // _S_copy_chars is a separate template to permit specialization
...@@ -979,9 +978,10 @@ namespace std ...@@ -979,9 +978,10 @@ namespace std
*/ */
basic_string& basic_string&
insert(size_type __pos, size_type __n, _CharT __c) insert(size_type __pos, size_type __n, _CharT __c)
{ {
this->insert(_M_check(__pos), __n, __c); const iterator __iterator = this->_M_ibegin()
return *this; + _M_check(__pos, "basic_string::insert");
return this->replace(__iterator, __iterator, __n, __c);
} }
/** /**
...@@ -1002,7 +1002,7 @@ namespace std ...@@ -1002,7 +1002,7 @@ namespace std
{ {
_GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend()); _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
const size_type __pos = __p - _M_ibegin(); const size_type __pos = __p - _M_ibegin();
this->insert(_M_check(__pos), size_type(1), __c); this->replace(__p, __p, size_type(1), __c);
_M_rep()->_M_set_leaked(); _M_rep()->_M_set_leaked();
return this->_M_ibegin() + __pos; return this->_M_ibegin() + __pos;
} }
...@@ -1043,7 +1043,8 @@ namespace std ...@@ -1043,7 +1043,8 @@ namespace std
basic_string& basic_string&
erase(size_type __pos = 0, size_type __n = npos) erase(size_type __pos = 0, size_type __n = npos)
{ {
return this->replace(_M_check(__pos), _M_fold(__pos, __n), return this->replace(_M_ibegin() + _M_check(__pos, "basic_string::erase"),
_M_ibegin() + __pos + _M_limit(__pos, __n),
_M_data(), _M_data()); _M_data(), _M_data());
} }
...@@ -1195,7 +1196,9 @@ namespace std ...@@ -1195,7 +1196,9 @@ namespace std
*/ */
basic_string& basic_string&
replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
{ return this->replace(_M_check(__pos), _M_fold(__pos, __n1), __n2, __c); } { return this->replace(_M_ibegin() + _M_check(__pos, "basic_string::replace"),
_M_ibegin() + __pos + _M_limit(__pos, __n1),
__n2, __c); }
/** /**
* @brief Replace range of characters with string. * @brief Replace range of characters with string.
...@@ -1843,11 +1846,7 @@ namespace std ...@@ -1843,11 +1846,7 @@ namespace std
*/ */
basic_string basic_string
substr(size_type __pos = 0, size_type __n = npos) const substr(size_type __pos = 0, size_type __n = npos) const
{ { return basic_string(*this, _M_check(__pos, "basic_string::substr"), __n); }
if (__pos > this->size())
__throw_out_of_range(__N("basic_string::substr"));
return basic_string(*this, __pos, __n);
}
/** /**
* @brief Compare to a string. * @brief Compare to a string.
......
...@@ -206,16 +206,20 @@ namespace std ...@@ -206,16 +206,20 @@ namespace std
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>:: basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string& __str, size_type __pos, size_type __n) basic_string(const basic_string& __str, size_type __pos, size_type __n)
: _M_dataplus(_S_construct(__str._M_check(__pos), : _M_dataplus(_S_construct(__str._M_ibegin()
__str._M_fold(__pos, __n), _Alloc()), _Alloc()) + __str._M_check(__pos, "basic_string::basic_string"),
__str._M_ibegin() + __pos + __str._M_limit(__pos, __n),
_Alloc()), _Alloc())
{ } { }
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>:: basic_string<_CharT, _Traits, _Alloc>::
basic_string(const basic_string& __str, size_type __pos, basic_string(const basic_string& __str, size_type __pos,
size_type __n, const _Alloc& __a) size_type __n, const _Alloc& __a)
: _M_dataplus(_S_construct(__str._M_check(__pos), : _M_dataplus(_S_construct(__str._M_ibegin()
__str._M_fold(__pos, __n), __a), __a) + __str._M_check(__pos, "basic_string::basic_string"),
__str._M_ibegin() + __pos + __str._M_limit(__pos, __n),
__a), __a)
{ } { }
// TBD: DPG annotate // TBD: DPG annotate
...@@ -268,12 +272,9 @@ namespace std ...@@ -268,12 +272,9 @@ namespace std
basic_string<_CharT, _Traits, _Alloc>:: basic_string<_CharT, _Traits, _Alloc>::
assign(const basic_string& __str, size_type __pos, size_type __n) assign(const basic_string& __str, size_type __pos, size_type __n)
{ {
const size_type __strsize = __str.size(); return this->assign(__str._M_data()
if (__pos > __strsize) + __str._M_check(__pos, "basic_string::assign"),
__throw_out_of_range("basic_string::assign"); __str._M_limit(__pos, __n));
const bool __testn = __n < __strsize - __pos;
const size_type __newsize = __testn ? __n : __strsize - __pos;
return this->assign(__str._M_data() + __pos, __newsize);
} }
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
...@@ -307,12 +308,9 @@ namespace std ...@@ -307,12 +308,9 @@ namespace std
insert(size_type __pos1, const basic_string& __str, insert(size_type __pos1, const basic_string& __str,
size_type __pos2, size_type __n) size_type __pos2, size_type __n)
{ {
const size_type __strsize = __str.size(); return this->insert(__pos1, __str._M_data()
if (__pos2 > __strsize) + __str._M_check(__pos2, "basic_string::insert"),
__throw_out_of_range("basic_string::insert"); __str._M_limit(__pos2, __n));
const bool __testn = __n < __strsize - __pos2;
const size_type __newsize = __testn ? __n : __strsize - __pos2;
return this->insert(__pos1, __str._M_data() + __pos2, __newsize);
} }
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
...@@ -321,13 +319,11 @@ namespace std ...@@ -321,13 +319,11 @@ namespace std
insert(size_type __pos, const _CharT* __s, size_type __n) insert(size_type __pos, const _CharT* __s, size_type __n)
{ {
__glibcxx_requires_string_len(__s, __n); __glibcxx_requires_string_len(__s, __n);
const size_type __size = this->size(); __pos = _M_check(__pos, "basic_string::insert");
if (__pos > __size) if (this->size() > this->max_size() - __n)
__throw_out_of_range("basic_string::insert");
if (__size > this->max_size() - __n)
__throw_length_error("basic_string::insert"); __throw_length_error("basic_string::insert");
if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data()) if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
|| less<const _CharT*>()(_M_data() + __size, __s)) || less<const _CharT*>()(_M_data() + this->size(), __s))
return _M_replace_safe(_M_ibegin() + __pos, _M_ibegin() + __pos, return _M_replace_safe(_M_ibegin() + __pos, _M_ibegin() + __pos,
__s, __s + __n); __s, __s + __n);
else else
...@@ -359,20 +355,17 @@ namespace std ...@@ -359,20 +355,17 @@ namespace std
size_type __n2) size_type __n2)
{ {
__glibcxx_requires_string_len(__s, __n2); __glibcxx_requires_string_len(__s, __n2);
const size_type __size = this->size(); __pos = _M_check(__pos, "basic_string::replace");
if (__pos > __size) __n1 = _M_limit(__pos, __n1);
__throw_out_of_range("basic_string::replace"); if (this->size() - __n1 > this->max_size() - __n2)
const bool __testn1 = __n1 < __size - __pos;
const size_type __foldn1 = __testn1 ? __n1 : __size - __pos;
if (__size - __foldn1 > this->max_size() - __n2)
__throw_length_error("basic_string::replace"); __throw_length_error("basic_string::replace");
if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data()) if (_M_rep()->_M_is_shared() || less<const _CharT*>()(__s, _M_data())
|| less<const _CharT*>()(_M_data() + __size, __s)) || less<const _CharT*>()(_M_data() + this->size(), __s))
return _M_replace_safe(_M_ibegin() + __pos, return _M_replace_safe(_M_ibegin() + __pos,
_M_ibegin() + __pos + __foldn1, __s, __s + __n2); _M_ibegin() + __pos + __n1, __s, __s + __n2);
// Todo: optimized in-place replace. // Todo: optimized in-place replace.
else else
return _M_replace(_M_ibegin() + __pos, _M_ibegin() + __pos + __foldn1, return _M_replace(_M_ibegin() + __pos, _M_ibegin() + __pos + __n1,
__s, __s + __n2); __s, __s + __n2);
} }
...@@ -674,45 +667,25 @@ namespace std ...@@ -674,45 +667,25 @@ namespace std
replace(size_type __pos1, size_type __n1, const basic_string& __str, replace(size_type __pos1, size_type __n1, const basic_string& __str,
size_type __pos2, size_type __n2) size_type __pos2, size_type __n2)
{ {
const size_type __strsize = __str.size(); return this->replace(__pos1, __n1, __str._M_data()
if (__pos2 > __strsize) + __str._M_check(__pos2, "basic_string::replace"),
__throw_out_of_range("basic_string::replace"); __str._M_limit(__pos2, __n2));
const bool __testn2 = __n2 < __strsize - __pos2;
const size_type __foldn2 = __testn2 ? __n2 : __strsize - __pos2;
return this->replace(__pos1, __n1,
__str._M_data() + __pos2, __foldn2);
} }
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>&
basic_string<_CharT, _Traits, _Alloc>:: basic_string<_CharT, _Traits, _Alloc>::
append(const basic_string& __str) append(const basic_string& __str)
{ { return this->append(__str._M_data(), __str.size()); }
// Iff appending itself, string needs to pre-reserve the
// correct size so that _M_mutate does not clobber the
// iterators 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(_M_iend(), _M_iend(), __str._M_ibegin(),
__str._M_iend());
}
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>& basic_string<_CharT, _Traits, _Alloc>&
basic_string<_CharT, _Traits, _Alloc>:: basic_string<_CharT, _Traits, _Alloc>::
append(const basic_string& __str, size_type __pos, size_type __n) append(const basic_string& __str, size_type __pos, size_type __n)
{ {
// Iff appending itself, string needs to pre-reserve the return this->append(__str._M_data()
// correct size so that _M_mutate does not clobber the + __str._M_check(__pos, "basic_string::append"),
// iterators formed here. __str._M_limit(__pos, __n));
const size_type __len = std::min(size_type(__str.size() - __pos),
__n) + this->size();
if (__len > this->capacity())
this->reserve(__len);
return _M_replace_safe(_M_iend(), _M_iend(), __str._M_check(__pos),
__str._M_fold(__pos, __n));
} }
template<typename _CharT, typename _Traits, typename _Alloc> template<typename _CharT, typename _Traits, typename _Alloc>
...@@ -720,6 +693,9 @@ namespace std ...@@ -720,6 +693,9 @@ namespace std
basic_string<_CharT, _Traits, _Alloc>:: basic_string<_CharT, _Traits, _Alloc>::
append(const _CharT* __s, size_type __n) append(const _CharT* __s, size_type __n)
{ {
// Iff appending itself, string needs to pre-reserve the
// correct size so that _M_mutate does not clobber the
// iterators formed here.
__glibcxx_requires_string_len(__s, __n); __glibcxx_requires_string_len(__s, __n);
const size_type __len = __n + this->size(); const size_type __len = __n + this->size();
if (__len > this->capacity()) if (__len > this->capacity())
...@@ -762,11 +738,8 @@ namespace std ...@@ -762,11 +738,8 @@ namespace std
basic_string<_CharT, _Traits, _Alloc>:: basic_string<_CharT, _Traits, _Alloc>::
copy(_CharT* __s, size_type __n, size_type __pos) const copy(_CharT* __s, size_type __n, size_type __pos) const
{ {
if (__pos > this->size()) __pos = _M_check(__pos, "basic_string::copy");
__throw_out_of_range("basic_string::copy"); __n = _M_limit(__pos, __n);
if (__n > this->size() - __pos)
__n = this->size() - __pos;
__glibcxx_requires_string_len(__s, __n); __glibcxx_requires_string_len(__s, __n);
...@@ -962,16 +935,13 @@ namespace std ...@@ -962,16 +935,13 @@ namespace std
basic_string<_CharT, _Traits, _Alloc>:: basic_string<_CharT, _Traits, _Alloc>::
compare(size_type __pos, size_type __n, const basic_string& __str) const compare(size_type __pos, size_type __n, const basic_string& __str) const
{ {
const size_type __size = this->size(); __pos = _M_check(__pos, "basic_string::compare");
__n = _M_limit(__pos, __n);
const size_type __osize = __str.size(); const size_type __osize = __str.size();
if (__pos > __size) const size_type __len = std::min(__n, __osize);
__throw_out_of_range("basic_string::compare");
const size_type __rsize= std::min(size_type(__size - __pos), __n);
const size_type __len = std::min(__rsize, __osize);
int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len);
if (!__r) if (!__r)
__r = __rsize - __osize; __r = __n - __osize;
return __r; return __r;
} }
...@@ -981,18 +951,15 @@ namespace std ...@@ -981,18 +951,15 @@ namespace std
compare(size_type __pos1, size_type __n1, const basic_string& __str, compare(size_type __pos1, size_type __n1, const basic_string& __str,
size_type __pos2, size_type __n2) const size_type __pos2, size_type __n2) const
{ {
const size_type __size = this->size(); __pos1 = _M_check(__pos1, "basic_string::compare");
const size_type __osize = __str.size(); __pos2 = __str._M_check(__pos2, "basic_string::compare");
if (__pos1 > __size || __pos2 > __osize) __n1 = _M_limit(__pos1, __n1);
__throw_out_of_range("basic_string::compare"); __n2 = __str._M_limit(__pos2, __n2);
const size_type __len = std::min(__n1, __n2);
const size_type __rsize = std::min(size_type(__size - __pos1), __n1);
const size_type __rosize = std::min(size_type(__osize - __pos2), __n2);
const size_type __len = std::min(__rsize, __rosize);
int __r = traits_type::compare(_M_data() + __pos1, int __r = traits_type::compare(_M_data() + __pos1,
__str.data() + __pos2, __len); __str.data() + __pos2, __len);
if (!__r) if (!__r)
__r = __rsize - __rosize; __r = __n1 - __n2;
return __r; return __r;
} }
...@@ -1003,7 +970,6 @@ namespace std ...@@ -1003,7 +970,6 @@ namespace std
compare(const _CharT* __s) const compare(const _CharT* __s) const
{ {
__glibcxx_requires_string(__s); __glibcxx_requires_string(__s);
const size_type __size = this->size(); const size_type __size = this->size();
const size_type __osize = traits_type::length(__s); const size_type __osize = traits_type::length(__s);
const size_type __len = std::min(__size, __osize); const size_type __len = std::min(__size, __osize);
...@@ -1020,17 +986,13 @@ namespace std ...@@ -1020,17 +986,13 @@ namespace std
compare(size_type __pos, size_type __n1, const _CharT* __s) const compare(size_type __pos, size_type __n1, const _CharT* __s) const
{ {
__glibcxx_requires_string(__s); __glibcxx_requires_string(__s);
__pos = _M_check(__pos, "basic_string::compare");
const size_type __size = this->size(); __n1 = _M_limit(__pos, __n1);
if (__pos > __size)
__throw_out_of_range("basic_string::compare");
const size_type __osize = traits_type::length(__s); const size_type __osize = traits_type::length(__s);
const size_type __rsize = std::min(size_type(__size - __pos), __n1); const size_type __len = std::min(__n1, __osize);
const size_type __len = std::min(__rsize, __osize);
int __r = traits_type::compare(_M_data() + __pos, __s, __len); int __r = traits_type::compare(_M_data() + __pos, __s, __len);
if (!__r) if (!__r)
__r = __rsize - __osize; __r = __n1 - __osize;
return __r; return __r;
} }
...@@ -1041,16 +1003,12 @@ namespace std ...@@ -1041,16 +1003,12 @@ namespace std
size_type __n2) const size_type __n2) const
{ {
__glibcxx_requires_string_len(__s, __n2); __glibcxx_requires_string_len(__s, __n2);
__pos = _M_check(__pos, "basic_string::compare");
const size_type __size = this->size(); __n1 = _M_limit(__pos, __n1);
if (__pos > __size) const size_type __len = std::min(__n1, __n2);
__throw_out_of_range("basic_string::compare");
const size_type __rsize = std::min(size_type(__size - __pos), __n1);
const size_type __len = std::min(__rsize, __n2);
int __r = traits_type::compare(_M_data() + __pos, __s, __len); int __r = traits_type::compare(_M_data() + __pos, __s, __len);
if (!__r) if (!__r)
__r = __rsize - __n2; __r = __n1 - __n2;
return __r; return __r;
} }
......
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