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] Specialize string::replace


Hi all,

now that we have branched I'd like to proceed for 3.2 with the
implementation of the string class improvements outlined
by Nathan. Below you will find a patch which specializes

template<class _InputIterator>
  basic_string&
  replace(iterator __i1, iterator __i2,
          _InputIterator __k1, _InputIterator __k2)

for the common cases of _InputIterator as pointer, const pointer,
iterator and const_iterator. It is overall quite straightforward
and indeed I have verified that it enables the optimization of the
assign, insert and replace members which have the source data
specified in terms of iterators. My only doubt is about the ugly
reinterpret_cast: is there any cleaner way to obtain from a _CharT*,
iterator or const_iterator, the required const _CharT* ?

Tested i686-pc-linux-gnu, as usual.

Nathan, is it Ok with you?

Ciao, Paolo.

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

2002-03-25  Paolo Carlini  <pcarlini@unitus.it>
            Nathan Myers  <ncm@cantrip.org>

        * include/bits/basic_string.h
        (replace(i1, i2, _CharT* k1, _CharT* k2),
        replace(i1, i2, const _CharT* k1, const _CharT* k2),
        replace(i1, i2, iterator k1, iterator k2),
        replace(i1, i2, const_iterator k1, const_iterator k2)):
        New, specializations to optimize for the common cases of
        pointers and iterators.
        (replace(pos, n1, s, n2)): Tweak.
        * include/bits/basic_string.tcc: Tweak comments.

diff -urN libstdc++-v3-orig/include/bits/basic_string.h 
libstdc++-v3/include/bits/basic_string.h
--- libstdc++-v3-orig/include/bits/basic_string.h    Wed Mar  6 22:22:52 
2002
+++ libstdc++-v3/include/bits/basic_string.h    Mon Mar 25 02:19:08 2002
@@ -647,8 +647,8 @@
         || less<const _CharT*>()(_M_data() + __size, __s))
       return _M_replace_safe(_M_ibegin() + __pos,
                  _M_ibegin() + __pos + __foldn1, __s, __s + __n2);   
-    else return this->replace(_M_check(__pos), _M_fold(__pos, __n1),
-                  __s, __s + __n2);
+    else return replace(_M_check(__pos), _M_fold(__pos, __n1),
+                basic_string(__s, __s + __n2));
       }
 
       basic_string&
@@ -682,6 +682,27 @@
         { return _M_replace(__i1, __i2, __k1, __k2,
          typename iterator_traits<_InputIterator>::iterator_category()); }
 
+      basic_string&
+      replace(iterator __i1, iterator __i2, _CharT* __k1, _CharT* __k2)
+        { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+                   reinterpret_cast<const _CharT*>(__k1), __k2 - __k1); }
+
+      basic_string&
+      replace(iterator __i1, iterator __i2, const _CharT* __k1, const 
_CharT* __k2)
+        { return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __k1, 
__k2 - __k1); }
+
+      basic_string&
+      replace(iterator __i1, iterator __i2, iterator __k1, iterator __k2)
+        { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+                   reinterpret_cast<const _CharT*>(&*__k1), __k2 - __k1);
+    }
+
+      basic_string&
+      replace(iterator __i1, iterator __i2, const_iterator __k1, 
const_iterator __k2)
+        { return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
+                   reinterpret_cast<const _CharT*>(&*__k1), __k2 - __k1);
+    }
+
     private:
       template<class _InputIterator>
         basic_string&
@@ -690,8 +711,8 @@
 
       template<class _ForwardIterator>
         basic_string&
-        _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator 
__k1,
-           _ForwardIterator __k2);
+        _M_replace_safe(iterator __i1, iterator __i2, _ForwardIterator 
__k1,
+            _ForwardIterator __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 -urN libstdc++-v3-orig/include/bits/basic_string.tcc 
libstdc++-v3/include/bits/basic_string.tcc
--- libstdc++-v3-orig/include/bits/basic_string.tcc    Tue Mar 12 
23:10:33 2002
+++ libstdc++-v3/include/bits/basic_string.tcc    Mon Mar 25 00:33:58 2002
@@ -498,13 +498,6 @@
       // 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>&
@@ -518,10 +511,8 @@
       }
 
   // This is a special replace helper, which does not buffer internally
-  // and can be used in the "safe" situations involving forward-iterators,
+  // and can be used in "safe" situations involving forward-iterators,
   // i.e., when source and destination ranges are known to not overlap.
-  // Presently, is called by _M_replace, by the various append and by
-  // the assigns.
   template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _ForwardIter>
       basic_string<_CharT, _Traits, _Alloc>&




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