--- stdcxx-4.2.1/include/string.cc	2008-04-24 20:23:57.000000000 -0400
+++ stdcxx-4.2.1/include/string.cc	2011-02-10 15:40:53.807995775 -0500
@@ -34,6 +34,7 @@
 #  pragma warning (disable: 4345)
 #endif   // _MSC_VER
 
+#include <rw/_typetraits.h>
 
 _RWSTD_NAMESPACE (std) {
 
@@ -256,6 +257,12 @@
 
     const size_type __rlen = _C_min (__str.size () - __pos, __n);
 
+	_RWSTD_REQUIRES (size () < max_size () - __rlen,
+			(_RWSTD_ERROR_LENGTH_ERROR,
+			 _RWSTD_FUNC ("basic_string::assign (const "
+			 	"basic_string&, size_type, size_type)"),
+				 size (), max_size () - __rlen));
+
     return replace (size_type (), size (), __str, __pos, __rlen);
 }
 
@@ -274,7 +281,7 @@
     
     const size_type __rlen = _C_min (__str.size () - __pos2, __n);
 
-    _RWSTD_REQUIRES (size () <= max_size () - __rlen,
+    _RWSTD_REQUIRES (size () < max_size () - __rlen,
                      (_RWSTD_ERROR_LENGTH_ERROR,
                       _RWSTD_FUNC ("basic_string::insert (size_type, const "
                                    "basic_string&, size_type, size_type)"), 
@@ -295,7 +302,7 @@
                                    "basic_string&)"),
                       __pos1, size ()));
     
-    _RWSTD_REQUIRES (size () <= max_size () - __str.size (),
+    _RWSTD_REQUIRES (size () < max_size () - __str.size (),
                      (_RWSTD_ERROR_LENGTH_ERROR,
                       _RWSTD_FUNC ("basic_string::insert (size_type, "
                                    "const basic_string&)"),
@@ -312,9 +319,6 @@
 {
     const size_type __size0 = size ();
 
-    if (npos == __n2)
-        __n2 = traits_type::length (__s);
-
     _RWSTD_REQUIRES (__pos1 <= __size0,
                      (_RWSTD_ERROR_OUT_OF_RANGE, 
                      _RWSTD_FUNC ("basic_string::replace (size_type, size_type"
@@ -324,13 +328,13 @@
     // number of characters to delete
     const size_type __xlen = _C_min (__n1, __size0 - __pos1);
 
-    _RWSTD_REQUIRES (__n2 <= max_size (),
+    _RWSTD_REQUIRES (__n2 < max_size (),
                      (_RWSTD_ERROR_LENGTH_ERROR,
                      _RWSTD_FUNC ("basic_string::replace (size_type, size_type"
                                   ", const_pointer, size_type)"), 
                      __n2, max_size ()));
 
-    _RWSTD_REQUIRES (__size0 - __xlen <= max_size () - __n2,
+    _RWSTD_REQUIRES (__size0 - __xlen < max_size () - __n2,
                      (_RWSTD_ERROR_LENGTH_ERROR,
                      _RWSTD_FUNC ("basic_string::replace (size_type, size_type"
                                   ", const_pointer, size_type)"), 
@@ -405,7 +409,7 @@
 
     const size_type __xlen = _C_min (__size0 - __pos, __len);
 
-    _RWSTD_REQUIRES (__size0 - __xlen <= max_size () - __count,
+    _RWSTD_REQUIRES (__size0 - __xlen < max_size () - __count,
                      (_RWSTD_ERROR_LENGTH_ERROR,
                       _RWSTD_FUNC ("basic_string::replace (size_type, "
                                    "size_type, size_type, value_type)"), 
@@ -477,6 +481,8 @@
     typedef _TYPENAME traits_type::char_type      value_type;
     typedef _Alloc                                allocator_type;
     typedef _TYPENAME allocator_type::size_type   size_type;
+    typedef _TYPENAME allocator_type::pointer     pointer;
+    typedef _TYPENAME allocator_type::const_pointer     const_pointer;
 
     typedef _STD::basic_string<_CharT, _Traits, _Alloc> _C_string_type;
 
@@ -513,10 +519,33 @@
         return __s.replace (__pos, __n, size_type (), value_type ());
     }
 
+    if (_RW::__rw_is_pointer<_InputIter>::_C_val) {
+        const const_pointer __beg1 = __s.data ();
+        const const_pointer __end1 = __s.data () + __s.size ();
+
+	const const_pointer __beg2 =
+		_RWSTD_REINTERPRET_CAST (const_pointer,
+			__s.get_allocator().address (*__first2));
+
+	const const_pointer __end2 =
+		_RWSTD_REINTERPRET_CAST (const_pointer,
+			__s.get_allocator().address (*__last2));
+
+        // ranges don't overlap, do simple replace
+        if (__end1 < __beg2 || __end2 < __beg1)
+            return __s.__replace_aux (__first1, __last1, __first2, __last2);
+
+        // otherwise fall through and make a copy first
+    }
+
      // use a (probably) faster algorithm if possible
     if (_STD::__is_bidirectional_iterator (_RWSTD_ITERATOR_CATEGORY(_InputIter,
-                                                                    __last2)))
-        return __s.__replace_aux (__first1, __last1, __first2, __last2);
+                                                                    __last2))) {
+        _C_string_type __s3;
+        __s3.__replace_aux (__s3.begin (), __s3.begin (), __first2, __last2);
+
+        return __s.__replace_aux (__first1, __last1, __s3.begin (), __s3.end ());
+    }
 
     _C_string_type __s3;
     _TYPENAME _C_string_type::iterator __first3 = __s3.begin ();
@@ -583,6 +612,9 @@
     typedef _RW::__string_ref<value_type, traits_type, allocator_type>
     _C_string_ref_type;
 
+	typedef _RWSTD_ALLOC_TYPE (allocator_type, value_type)
+	_C_value_alloc_type;
+
 #  else   // if !defined (_RWSTD_NO_STRING_OUTLINED_MEMBER_TEMPLATES)
 
 template<class _CharT, class _Traits, class _Allocator>
@@ -596,6 +628,8 @@
 
 #  endif  // _RWSTD_NO_STRING_OUTLINED_MEMBER_TEMPLATES
 
+    // assumes that the two ranges do not overlap
+
     _RWSTD_ASSERT_RANGE (__first1, __s._C_make_iter (__s._C_data 
                                                      + __s.size ()));
     _RWSTD_ASSERT_RANGE (__first1, __last1);
@@ -615,7 +649,7 @@
     size_type __slen = __ssize - __pos;
     size_type __xlen = __n < __slen ? __n : __slen; 
 
-    _RWSTD_REQUIRES (__ssize - __xlen <= __s.max_size () - __n2,
+    _RWSTD_REQUIRES (__ssize - __xlen < __s.max_size () - __n2,
                      (_RWSTD_ERROR_LENGTH_ERROR, 
                       _RWSTD_FUNC ("basic_string::__replace_aux (iterator, "
                                    "iterator, InputIterator, InputIterator)"),
@@ -650,15 +684,37 @@
             __s._C_unlink (__temp->data ());
         }
         else {
+	    pointer __tmp = 0;
+
+	    if (__n2) {
+		const_reference __ref =
+			_RWSTD_REINTERPRET_CAST (const_reference, *__first2);
+
+		const const_pointer __ptr = __s.get_allocator().address (__ref);
+
+		if (__s.data () <= __ptr && __s.data () + __ssize > __ptr) {
+			__tmp = __s.get_allocator().allocate (__n2);
+
+			for (__d = 0; __d < __n2; __d++)
+			    traits_type::assign (*(__tmp + __d), *__first2++);
+		}
+	 }
+
             // Current reference has enough room.
             if (__rem)
                 traits_type::move (__s._C_data + __pos + __n2,
                                    __s._C_data + __pos + __n, 
                                    __rem);
 
+	     if (__tmp) {
+		traits_type::copy (__s._C_data + __pos, __tmp, __n2);
+		__s.get_allocator().deallocate (__tmp, __n2);
+	     }
+	     else {
             for (__d = 0; __d < __n2; __d++)
                 traits_type::assign (*(__s._C_data + __pos + __d),
                                      *__first2++);
+	     }
 
             __s._C_pref ()->_C_size._C_size = __len;
             traits_type::assign (__s._C_data [__len], value_type ());
