aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo@gcc.gnu.org>2001-12-10 13:42:01 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2001-12-10 13:42:01 +0000
commit78bd50313ea03c26bff96ec9d0304f8970beb88a (patch)
treeb218cd0b04b3da48f0c5a6e43128bcda76ccbe76
parent96a9c44f09cf8eec4ebf9469b32ab187d113f9af (diff)
downloadgcc-78bd50313ea03c26bff96ec9d0304f8970beb88a.zip
gcc-78bd50313ea03c26bff96ec9d0304f8970beb88a.tar.gz
gcc-78bd50313ea03c26bff96ec9d0304f8970beb88a.tar.bz2
basic_string.tcc (_M_replace_safe): New function.
2001-12-10 Paolo Carlini <pcarlini@unitus.it> Nathan Myers <ncm@cantrip.org> * include/bits/basic_string.tcc (_M_replace_safe): New function. (_M_replace(input_iterator_tag), append members): Use it. (_M_replace(forward_iterator_tag)): Remove. * include/bits/basic_string.h: Adjust declarations. * src/string-inst.cc: Adjust declarations. From-SVN: r47844
-rw-r--r--libstdc++-v3/include/bits/basic_string.h6
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc43
-rw-r--r--libstdc++-v3/src/string-inst.cc25
3 files changed, 49 insertions, 25 deletions
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 8c5caff..406d71c 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -639,10 +639,10 @@ namespace std
_M_replace(iterator __i1, iterator __i2, _InputIterator __k1,
_InputIterator __k2, input_iterator_tag);
- template<class _FwdIterator>
+ template<class _InputIterator>
basic_string&
- _M_replace(iterator __i1, iterator __i2, _FwdIterator __k1,
- _FwdIterator __k2, forward_iterator_tag);
+ _M_replace_safe(iterator __i1, iterator __i2, _InputIterator __k1,
+ _InputIterator __k2);
// _S_construct_aux is used to implement the 21.3.1 para 15 which
// requires special behaviour if _InIter is an integral type
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 8081304..57a5191 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -490,6 +490,13 @@ namespace std
// else nothing (in particular, avoid calling _M_mutate() unnecessarily.)
}
+ // This is the general replace helper, which gets instantiated both
+ // for input-iterators and forward-iterators. It buffers internally and
+ // then calls _M_replace_safe. For input-iterators this is almost the
+ // best we can do, but for forward-iterators many optimizations could be
+ // conceived: f.i., when source and destination ranges do not overlap
+ // buffering is not really needed. In order to easily implement them, it
+ // could become useful to add an _M_replace(forward_iterator_tag)
template<typename _CharT, typename _Traits, typename _Alloc>
template<typename _InputIter>
basic_string<_CharT, _Traits, _Alloc>&
@@ -497,16 +504,21 @@ namespace std
_M_replace(iterator __i1, iterator __i2, _InputIter __k1,
_InputIter __k2, input_iterator_tag)
{
+ // Save concerned source string data in a temporary.
basic_string __s(__k1, __k2);
- return this->replace(__i1, __i2, __s._M_ibegin(), __s._M_iend());
+ return _M_replace_safe(__i1, __i2, __s._M_ibegin(), __s._M_iend());
}
+ // This is a special replace helper, which does not buffer internally
+ // and can be used in the "safe" situations involving forward-iterators,
+ // i.e., when source and destination ranges are known to not overlap.
+ // Presently, is called by _M_replace and by the various append.
template<typename _CharT, typename _Traits, typename _Alloc>
- template<typename _ForwardIter>
+ template<typename _InputIter>
basic_string<_CharT, _Traits, _Alloc>&
basic_string<_CharT, _Traits, _Alloc>::
- _M_replace(iterator __i1, iterator __i2, _ForwardIter __k1,
- _ForwardIter __k2, forward_iterator_tag)
+ _M_replace_safe(iterator __i1, iterator __i2, _InputIter __k1,
+ _InputIter __k2)
{
size_type __dnew = static_cast<size_type>(distance(__k1, __k2));
size_type __dold = __i2 - __i1;
@@ -515,16 +527,11 @@ namespace std
if (__dmax <= __dnew)
__throw_length_error("basic_string::_M_replace");
size_type __off = __i1 - _M_ibegin();
-
- // Save concerned source string data in a temporary.
- basic_string __temp(__k1, __k2);
_M_mutate(__off, __dold, __dnew);
-
- // Invalidated __i1, __i2 (and clobbered original source string
- // data when destination string == source string and the string
- // is unshared).
+
+ // Invalidated __i1, __i2
if (__dnew)
- _S_copy_chars(_M_data() + __off, __temp.begin(), __temp.end());
+ _S_copy_chars(_M_data() + __off, __k1, __k2);
return *this;
}
@@ -537,7 +544,7 @@ namespace std
{
return this->replace(_M_check(__pos1), _M_fold(__pos1, __n1),
__str._M_check(__pos2),
- __str._M_fold(__pos2, __n2));
+ __str._M_fold(__pos2, __n2));
}
template<typename _CharT, typename _Traits, typename _Alloc>
@@ -552,8 +559,8 @@ namespace std
size_type __len = __size + this->size();
if (__len > this->capacity())
this->reserve(__len);
- return this->replace(_M_iend(), _M_iend(), __str._M_ibegin(),
- __str._M_iend());
+ return _M_replace_safe(_M_iend(), _M_iend(), __str._M_ibegin(),
+ __str._M_iend());
}
template<typename _CharT, typename _Traits, typename _Alloc>
@@ -567,8 +574,8 @@ namespace std
size_type __len = min(__str.size() - __pos, __n) + this->size();
if (__len > this->capacity())
this->reserve(__len);
- return this->replace(_M_iend(), _M_iend(), __str._M_check(__pos),
- __str._M_fold(__pos, __n));
+ return _M_replace_safe(_M_iend(), _M_iend(), __str._M_check(__pos),
+ __str._M_fold(__pos, __n));
}
template<typename _CharT, typename _Traits, typename _Alloc>
@@ -579,7 +586,7 @@ namespace std
size_type __len = __n + this->size();
if (__len > this->capacity())
this->reserve(__len);
- return this->replace(_M_iend(), _M_iend(), __s, __s + __n);
+ return _M_replace_safe(_M_iend(), _M_iend(), __s, __s + __n);
}
template<typename _CharT, typename _Traits, typename _Alloc>
diff --git a/libstdc++-v3/src/string-inst.cc b/libstdc++-v3/src/string-inst.cc
index 54249b5..324ca86 100644
--- a/libstdc++-v3/src/string-inst.cc
+++ b/libstdc++-v3/src/string-inst.cc
@@ -71,21 +71,38 @@ namespace std
template
S&
S::_M_replace(S::iterator, S::iterator, S::iterator, S::iterator,
- forward_iterator_tag);
+ input_iterator_tag);
template
S&
S::_M_replace(S::iterator, S::iterator, S::const_iterator,
- S::const_iterator, forward_iterator_tag);
+ S::const_iterator, input_iterator_tag);
template
S&
- S::_M_replace(S::iterator, S::iterator, C*, C*, forward_iterator_tag);
+ S::_M_replace(S::iterator, S::iterator, C*, C*, input_iterator_tag);
template
S&
S::_M_replace(S::iterator, S::iterator, const C*, const C*,
- forward_iterator_tag);
+ input_iterator_tag);
+
+ template
+ S&
+ S::_M_replace_safe(S::iterator, S::iterator, S::iterator, S::iterator);
+
+ template
+ S&
+ S::_M_replace_safe(S::iterator, S::iterator, S::const_iterator,
+ S::const_iterator);
+
+ template
+ S&
+ S::_M_replace_safe(S::iterator, S::iterator, C*, C*);
+
+ template
+ S&
+ S::_M_replace_safe(S::iterator, S::iterator, const C*, const C*);
template
C*