This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] _M_replace clean up (take 2)


Hi,

privately, Nathan Myers pointed out a serious defect of my previous patch: when
true input-iterators are involved, distance cannot be used. Also, contrary to my
expectations, this case may *really* happen (not in the current testsuite ;)

Therefore, an unified _M_replace(input_iterator_tag) may avoid a double
redundant buffering (inside _M_replace(input_iterator_tag), and then, again,
inside _M_replace(forward_iterator_tag)) but has to be sligthly different from
the current _M_replace(forward_iterator_tag), which uses distance.

This is only a first *preparatory* step toward a really efficient solution,
which should be able to detect when buffering is not needed at all
(http://gcc.gnu.org/ml/libstdc++/2001-12/msg00142.html)

Tested i686-pc-linux-gnu.

Cheers,
Paolo.

//////////////

2001-12-09  Paolo Carlini  <pcarlini@unitus.it>
            Nathan Myers  <ncm@cantrip.org>

        * include/bits/basic_string.tcc (_M_replace(input_iterator_tag)):
        Remove.
        * include/bits/basic_string.h (_M_replace(forward_iterator_tag)):
        Adjust signature to input_iterator_tag and avoid using distance.
        * src/string-inst.cc: Adjust declarations.


diff -prN libstdc++-v3-orig/include/bits/basic_string.h
libstdc++-v3/include/bits/basic_string.h
*** libstdc++-v3-orig/include/bits/basic_string.h Sat Dec  8 17:57:02 2001
--- libstdc++-v3/include/bits/basic_string.h Sat Dec  8 18:29:10 2001
*************** namespace std
*** 639,649 ****
          _M_replace(iterator __i1, iterator __i2, _InputIterator __k1,
       _InputIterator __k2, input_iterator_tag);

-       template<class _FwdIterator>
-         basic_string&
-         _M_replace(iterator __i1, iterator __i2, _FwdIterator __k1,
-      _FwdIterator __k2, forward_iterator_tag);
-
        // _S_construct_aux is used to implement the 21.3.1 para 15 which
        // requires special behaviour if _InIter is an integral type
        template<class _InIter>
--- 639,644 ----
diff -prN libstdc++-v3-orig/include/bits/basic_string.tcc
libstdc++-v3/include/bits/basic_string.tcc
*** libstdc++-v3-orig/include/bits/basic_string.tcc Sat Dec  8 17:56:54 2001
--- libstdc++-v3/include/bits/basic_string.tcc Sun Dec  9 03:14:16 2001
*************** namespace std
*** 497,523 ****
        _M_replace(iterator __i1, iterator __i2, _InputIter __k1,
     _InputIter __k2, input_iterator_tag)
        {
-  basic_string __s(__k1, __k2);
-  return this->replace(__i1, __i2, __s._M_ibegin(), __s._M_iend());
-       }
-
-   template<typename _CharT, typename _Traits, typename _Alloc>
-     template<typename _ForwardIter>
-       basic_string<_CharT, _Traits, _Alloc>&
-       basic_string<_CharT, _Traits, _Alloc>::
-       _M_replace(iterator __i1, iterator __i2, _ForwardIter __k1,
-    _ForwardIter __k2, forward_iterator_tag)
-       {
-  size_type __dnew = static_cast<size_type>(distance(__k1, __k2));
   size_type __dold = __i2 - __i1;
-  size_type __dmax = this->max_size();
-
-  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
--- 497,508 ----
        _M_replace(iterator __i1, iterator __i2, _InputIter __k1,
     _InputIter __k2, input_iterator_tag)
        {
   size_type __dold = __i2 - __i1;
   size_type __off = __i1 - _M_ibegin();

   // Save concerned source string data in a temporary.
   basic_string __temp(__k1, __k2);
+  size_type __dnew = __temp.size();
   _M_mutate(__off, __dold, __dnew);

   // Invalidated __i1, __i2 (and clobbered original source string
diff -prN libstdc++-v3-orig/src/string-inst.cc libstdc++-v3/src/string-inst.cc
*** libstdc++-v3-orig/src/string-inst.cc Sat Dec  8 18:42:47 2001
--- libstdc++-v3/src/string-inst.cc Sat Dec  8 18:43:18 2001
*************** namespace std
*** 71,91 ****
    template
      S&
      S::_M_replace(S::iterator, S::iterator, S::iterator, S::iterator,
!     forward_iterator_tag);

    template
      S&
      S::_M_replace(S::iterator, S::iterator, S::const_iterator,
!     S::const_iterator, forward_iterator_tag);

    template
      S&
!     S::_M_replace(S::iterator, S::iterator, C*, C*, forward_iterator_tag);

    template
      S&
      S::_M_replace(S::iterator, S::iterator, const C*, const C*,
!     forward_iterator_tag);

    template
      C*
--- 71,91 ----
    template
      S&
      S::_M_replace(S::iterator, S::iterator, S::iterator, S::iterator,
!     input_iterator_tag);

    template
      S&
      S::_M_replace(S::iterator, S::iterator, S::const_iterator,
!     S::const_iterator, input_iterator_tag);

    template
      S&
!     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*,
!     input_iterator_tag);

    template
      C*



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]