This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[v3, v7-branch] string::append, other minor things


Hi,

I'm finally rather happy with the code :) Modulo bug fixes, will be also
the shape of ext/vstring.h delivered with 4.1.0.

Tested x86-linux, both string bases.

Paolo.

////////////////////
2005-12-02  Paolo Carlini  <pcarlini@suse.de>

	* include/bits/basic_string.h (basic_string<>::_M_append): New.
	(append(const basic_string&), append(const basic_string&,
	size_type, size_type), append(const _CharT*, size_type),
	append(const _CharT*)): Use it.
	(append(size_type, _CharT)): Delegate to _M_replace_aux.
	(assign(const basic_string&, size_type, size_type),
	assign(const _CharT*), replace(size_type, size_type,
	const _CharT*, size_type)): Forward to _M_replace.
	* include/bits/basic_string.tcc (basic_string<>::_M_append):
	Define, core append functionality.
	(_M_replace): Simplify, move __s == 0 case to _M_replace_aux.
	(_M_replace_aux): Reorganize, don't call _M_replace.
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h	(revision 107825)
+++ include/bits/basic_string.h	(working copy)
@@ -573,7 +573,8 @@
        *  @return  Reference to this string.
        */
       basic_string&
-      append(const basic_string& __str);
+      append(const basic_string& __str)
+      { return _M_append(__str._M_data(), __str.size()); }
 
       /**
        *  @brief  Append a substring.
@@ -588,7 +589,10 @@
        *  characters in @a str, the remainder of @a str is appended.
        */
       basic_string&
-      append(const basic_string& __str, size_type __pos, size_type __n);
+      append(const basic_string& __str, size_type __pos, size_type __n)
+      { return _M_append(__str._M_data()
+			 + __str._M_check(__pos, "basic_string::append"),
+			 __str._M_limit(__pos, __n)); }
 
       /**
        *  @brief  Append a C substring.
@@ -597,7 +601,12 @@
        *  @return  Reference to this string.
        */
       basic_string&
-      append(const _CharT* __s, size_type __n);
+      append(const _CharT* __s, size_type __n)
+      {
+	__glibcxx_requires_string_len(__s, __n);
+	_M_check_length(size_type(0), __n, "basic_string::append");
+	return _M_append(__s, __n);
+      }
 
       /**
        *  @brief  Append a C string.
@@ -608,7 +617,9 @@
       append(const _CharT* __s)
       {
 	__glibcxx_requires_string(__s);
-	return this->append(__s, traits_type::length(__s));
+	const size_type __n = traits_type::length(__s);
+	_M_check_length(size_type(0), __n, "basic_string::append");
+	return _M_append(__s, __n);
       }
 
       /**
@@ -620,7 +631,8 @@
        *  Appends n copies of c to this string.
        */
       basic_string&
-      append(size_type __n, _CharT __c);
+      append(size_type __n, _CharT __c)
+      { return _M_replace_aux(this->size(), size_type(0), __n, __c); }
 
       /**
        *  @brief  Append a range of characters.
@@ -675,9 +687,9 @@
        */
       basic_string&
       assign(const basic_string& __str, size_type __pos, size_type __n)
-      { return this->assign(__str._M_data()
-			    + __str._M_check(__pos, "basic_string::assign"),
-			    __str._M_limit(__pos, __n)); }
+      { return _M_replace(size_type(0), this->size(), __str._M_data()
+			  + __str._M_check(__pos, "basic_string::assign"),
+			  __str._M_limit(__pos, __n)); }
 
       /**
        *  @brief  Set value to a C substring.
@@ -709,7 +721,8 @@
       assign(const _CharT* __s)
       {
 	__glibcxx_requires_string(__s);
-	return this->assign(__s, traits_type::length(__s));
+	return _M_replace(size_type(0), this->size(), __s,
+			  traits_type::length(__s));
       }
 
       /**
@@ -1022,7 +1035,12 @@
       */
       basic_string&
       replace(size_type __pos, size_type __n1, const _CharT* __s,
-	      size_type __n2);
+	      size_type __n2)
+      {
+	__glibcxx_requires_string_len(__s, __n2);
+	return _M_replace(_M_check(__pos, "basic_string::replace"),
+			  _M_limit(__pos, __n1), __s, __n2);
+      }
 
       /**
        *  @brief  Replace characters with value of a C string.
@@ -1238,6 +1256,9 @@
       _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
 		 const size_type __len2);
 
+      basic_string&
+      _M_append(const _CharT* __s, size_type __n);
+
     public:
 
       /**
Index: include/bits/basic_string.tcc
===================================================================
--- include/bits/basic_string.tcc	(revision 107825)
+++ include/bits/basic_string.tcc	(working copy)
@@ -67,111 +67,37 @@
     }
 
   template<typename _CharT, typename _Traits, typename _Alloc>
-    basic_string<_CharT, _Traits, _Alloc>&
+    void
     basic_string<_CharT, _Traits, _Alloc>::
-    append(size_type __n, _CharT __c)
+    resize(size_type __n, _CharT __c)
     {
-      if (__n)
-	{
-	  _M_check_length(size_type(0), __n, "basic_string::append");	  
-	  const size_type __len = __n + this->size();
-	  if (__len > this->capacity() || this->_M_is_shared())
-	    this->_M_reserve(__len);
-	  this->_S_assign(this->_M_data() + this->size(), __n, __c);
-	  this->_M_set_length(__len);
-	}
-      return *this;
+      const size_type __size = this->size();
+      if (__size < __n)
+	this->append(__n - __size, __c);
+      else if (__n < __size)
+	this->_M_erase(__n, __size - __n);
     }
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>&
     basic_string<_CharT, _Traits, _Alloc>::
-    append(const _CharT* __s, size_type __n)
+    _M_append(const _CharT* __s, size_type __n)
     {
-      __glibcxx_requires_string_len(__s, __n);
-      if (__n)
-	{
-	  _M_check_length(size_type(0), __n, "basic_string::append");
-	  const size_type __len = __n + this->size();
-	  if (__len > this->capacity() || this->_M_is_shared())
-	    {
-	      if (this->_M_disjunct(__s))
-		this->_M_reserve(__len);
-	      else
-		{
-		  const size_type __off = __s - this->_M_data();
-		  this->_M_reserve(__len);
-		  __s = this->_M_data() + __off;
-		}
-	    }
-	  this->_S_copy(this->_M_data() + this->size(), __s, __n);
-	  this->_M_set_length(__len);
-	}
-      return *this;
-    }
+      const size_type __len = __n + this->size();
 
-  template<typename _CharT, typename _Traits, typename _Alloc>
-    basic_string<_CharT, _Traits, _Alloc>&
-    basic_string<_CharT, _Traits, _Alloc>::
-    append(const basic_string& __str)
-    {
-      const size_type __size = __str.size();
-      if (__size)
+      if (__len <= this->capacity() && !this->_M_is_shared())
 	{
-	  const size_type __len = __size + this->size();
-	  if (__len > this->capacity() || this->_M_is_shared())
-	    this->_M_reserve(__len);
-	  this->_S_copy(this->_M_data() + this->size(), __str._M_data(),
-			__size);
-	  this->_M_set_length(__len);
+	  if (__n)
+	    this->_S_copy(this->_M_data() + this->size(), __s, __n);
 	}
-      return *this;
-    }    
+      else
+	this->_M_mutate(this->size(), size_type(0), __s, __n);
 
-  template<typename _CharT, typename _Traits, typename _Alloc>
-    basic_string<_CharT, _Traits, _Alloc>&
-    basic_string<_CharT, _Traits, _Alloc>::
-    append(const basic_string& __str, size_type __pos, size_type __n)
-    {
-      __str._M_check(__pos, "basic_string::append");
-      __n = __str._M_limit(__pos, __n);
-      if (__n)
-	{
-	  const size_type __len = __n + this->size();
-	  if (__len > this->capacity() || this->_M_is_shared())
-	    this->_M_reserve(__len);
-	  this->_S_copy(this->_M_data() + this->size(),
-			__str._M_data() + __pos, __n);
-	  this->_M_set_length(__len);
-	}
+      this->_M_set_length(__len);
       return *this;
     }
 
   template<typename _CharT, typename _Traits, typename _Alloc>
-    basic_string<_CharT, _Traits, _Alloc>&
-    basic_string<_CharT, _Traits, _Alloc>::
-    replace(size_type __pos, size_type __n1, const _CharT* __s,
-	    size_type __n2)
-    {
-      __glibcxx_requires_string_len(__s, __n2);
-      _M_check(__pos, "basic_string::replace");
-      __n1 = _M_limit(__pos, __n1);
-      return _M_replace(__pos, __n1, __s, __n2);
-    }
-
-  template<typename _CharT, typename _Traits, typename _Alloc>
-    void
-    basic_string<_CharT, _Traits, _Alloc>::
-    resize(size_type __n, _CharT __c)
-    {
-      const size_type __size = this->size();
-      if (__size < __n)
-	this->append(__n - __size, __c);
-      else if (__n < __size)
-	this->_M_erase(__n, __size - __n);
-    }
-
-  template<typename _CharT, typename _Traits, typename _Alloc>
     template<typename _InputIterator>
       basic_string<_CharT, _Traits, _Alloc>&
       basic_string<_CharT, _Traits, _Alloc>::
@@ -190,9 +116,26 @@
     _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
 		   _CharT __c)
     {
-      _M_replace(__pos1, __n1, 0, __n2);
+      _M_check_length(__n1, __n2, "basic_string::_M_replace_aux");
+
+      const size_type __old_size = this->size();
+      const size_type __new_size = __old_size + __n2 - __n1;
+
+      if (__new_size <= this->capacity() && !this->_M_is_shared())
+	{
+	  _CharT* __p = this->_M_data() + __pos1;
+
+	  const size_type __how_much = __old_size - __pos1 - __n1;
+	  if (__how_much && __n1 != __n2)
+	    this->_S_move(__p + __n2, __p + __n1, __how_much);
+	}
+      else
+	this->_M_mutate(__pos1, __n1, 0, __n2);
+
       if (__n2)
 	this->_S_assign(this->_M_data() + __pos1, __n2, __c);
+
+      this->_M_set_length(__new_size);
       return *this;
     }
 
@@ -206,45 +149,41 @@
 
       const size_type __old_size = this->size();
       const size_type __new_size = __old_size + __len2 - __len1;
-      const size_type __how_much = __old_size - __pos - __len1;
       
       if (__new_size <= this->capacity() && !this->_M_is_shared())
 	{
 	  _CharT* __p = this->_M_data() + __pos;
-	  if (__s)
+
+	  const size_type __how_much = __old_size - __pos - __len1;
+	  if (_M_disjunct(__s))
 	    {
-	      if (_M_disjunct(__s))
+	      if (__how_much && __len1 != __len2)
+		this->_S_move(__p + __len2, __p + __len1, __how_much);
+	      if (__len2)
+		this->_S_copy(__p, __s, __len2);
+	    }
+	  else
+	    {
+	      // Work in-place.
+	      if (__len2 && __len2 <= __len1)
+		this->_S_move(__p, __s, __len2);
+	      if (__how_much && __len1 != __len2)
+		this->_S_move(__p + __len2, __p + __len1, __how_much);
+	      if (__len2 > __len1)
 		{
-		  if (__how_much && __len1 != __len2)
-		    this->_S_move(__p + __len2, __p + __len1, __how_much);
-		  if (__len2)
-		    this->_S_copy(__p, __s, __len2);
-		}
-	      else
-		{
-		  // Work in-place.
-		  if (__len2 && __len2 <= __len1)
+		  if (__s + __len2 <= __p + __len1)
 		    this->_S_move(__p, __s, __len2);
-		  if (__how_much && __len1 != __len2)
-		    this->_S_move(__p + __len2, __p + __len1, __how_much);
-		  if (__len2 > __len1)
+		  else if (__s >= __p + __len1)
+		    this->_S_copy(__p, __s + __len2 - __len1, __len2);
+		  else
 		    {
-		      if (__s + __len2 <= __p + __len1)
-			this->_S_move(__p, __s, __len2);
-		      else if (__s >= __p + __len1)
-			this->_S_copy(__p, __s + __len2 - __len1, __len2);
-		      else
-			{
-			  const size_type __nleft = (__p + __len1) - __s;
-			  this->_S_move(__p, __s, __nleft);
-			  this->_S_copy(__p + __nleft, __p + __len2,
-					__len2 - __nleft);
-			}
+		      const size_type __nleft = (__p + __len1) - __s;
+		      this->_S_move(__p, __s, __nleft);
+		      this->_S_copy(__p + __nleft, __p + __len2,
+				    __len2 - __nleft);
 		    }
 		}
 	    }
-	  else if (__how_much && __len1 != __len2)
-	    this->_S_move(__p + __len2, __p + __len1, __how_much);
 	}
       else
 	this->_M_mutate(__pos, __len1, __s, __len2);

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