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]

Re: debug shrink_to_fit


Here is a new proposition:

2011-06-09 François Dumont <francois.cppdevs@free.fr>

* include/bits/stl_vector.h, stl_deque.h, stl_bvector.h,
basic_string.h: Have schrink_to_fit return a boolean value to indicate
if it has been shrinked or not.
* include/ext/vstring.h: Likewise.
* include/bits/allocator.h (__shrink_to_fit): Use move iterator if
move constructor do not throw.
* include/debug/vector, deque, string: Add shrink_to_fit debug
implementation.
* testsuite/23_containers/vector/debug/shrink_to_fit.cc: New.
* testsuite/23_containers/deque/debug/shrink_to_fit.cc: New.
* testsuite/21_string/debug/shrink_to_fit.cc: New.


François

On 06/08/2011 09:43 PM, François Dumont wrote:
Ok thanks, if I can change shrink_to_fit signature it could be easier, indeed. I will submit the new patch tomorrow.

François

On 06/08/2011 01:06 PM, Paolo Carlini wrote:
... in fact, when I did this shrink_to_fit little piece of work I was probably "smoking crack". The below is perfectly fine and your fix should be much simpler on top of it.

Tested x86_64-linux.

Thanks,
Paolo.

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



Index: include/debug/vector
===================================================================
--- include/debug/vector	(revision 174814)
+++ include/debug/vector	(working copy)
@@ -280,7 +280,17 @@
 #endif
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
-      using _Base::shrink_to_fit;
+      bool
+      shrink_to_fit()
+      {
+	if (_Base::shrink_to_fit())
+	{
+	  _M_guaranteed_capacity = _Base::capacity();
+	  this->_M_invalidate_all();
+	  return true;
+	}
+	return false;
+      }
 #endif
 
       size_type
Index: include/debug/deque
===================================================================
--- include/debug/deque	(revision 174814)
+++ include/debug/deque	(working copy)
@@ -277,7 +277,15 @@
 #endif
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
-      using _Base::shrink_to_fit;
+      bool
+      shrink_to_fit()
+      {
+	if (_Base::shrink_to_fit()) {
+	  this->_M_invalidate_all();
+	  return true;
+	}
+	return false;
+      }
 #endif
 
       using _Base::empty;
Index: include/debug/string
===================================================================
--- include/debug/string	(revision 174814)
+++ include/debug/string	(working copy)
@@ -237,7 +237,15 @@
     { this->resize(__n, _CharT()); }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
-    using _Base::shrink_to_fit;
+    bool
+    shrink_to_fit()
+    {
+      if (_Base::shrink_to_fit()) {
+	this->_M_invalidate_all();
+	return true;
+      }
+      return false;
+    }
 #endif
 
     using _Base::capacity;
Index: include/ext/vstring.h
===================================================================
--- include/ext/vstring.h	(revision 174814)
+++ include/ext/vstring.h	(working copy)
@@ -462,13 +462,18 @@
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       /// A non-binding request to reduce capacity() to size().
-      void
+      bool
       shrink_to_fit()
       {
 	__try
-	  { this->reserve(0); }
+	  {
+	    if (capacity() == size())
+	      return false;
+	    this->reserve(0);
+	    return true;
+	  }
 	__catch(...)
-	  { }
+	  { return false; }
       }
 #endif
 
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h	(revision 174814)
+++ include/bits/basic_string.h	(working copy)
@@ -750,13 +750,18 @@
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       ///  A non-binding request to reduce capacity() to size().
-      void
+      bool
       shrink_to_fit()
       {
 	__try
-	  { reserve(0); }
+	  {
+	    if (size() == capacity())
+	      return false;
+	    reserve(0);
+	    return true;
+	  }
 	__catch(...)
-	  { }
+	  { return false; }
       }
 #endif
 
Index: include/bits/stl_vector.h
===================================================================
--- include/bits/stl_vector.h	(revision 174814)
+++ include/bits/stl_vector.h	(working copy)
@@ -644,9 +644,13 @@
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       /**  A non-binding request to reduce capacity() to size().  */
-      void
+      bool
       shrink_to_fit()
-      { std::__shrink_to_fit(*this); }
+      {
+	if (this->_M_impl._M_end_of_storage == this->_M_impl._M_finish)
+	  return false;
+	return std::__shrink_to_fit(*this);
+      }
 #endif
 
       /**
Index: include/bits/stl_deque.h
===================================================================
--- include/bits/stl_deque.h	(revision 174814)
+++ include/bits/stl_deque.h	(working copy)
@@ -1194,9 +1194,19 @@
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
       /**  A non-binding request to reduce memory use.  */
-      void
+      bool
       shrink_to_fit()
-      { std::__shrink_to_fit(*this); }
+      {
+	difference_type __front_capacity = this->_M_impl._M_start._M_cur
+					- this->_M_impl._M_start._M_first;
+	if (__front_capacity == 0)
+	  return false;
+	difference_type __back_capacity = this->_M_impl._M_finish._M_last
+					- this->_M_impl._M_finish._M_cur;
+	if (__front_capacity + __back_capacity < _S_buffer_size())
+	  return false;
+	return std::__shrink_to_fit(*this);
+      }
 #endif
 
       /**
Index: include/bits/stl_bvector.h
===================================================================
--- include/bits/stl_bvector.h	(revision 174814)
+++ include/bits/stl_bvector.h	(working copy)
@@ -842,9 +842,13 @@
     }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
-    void
+    bool
     shrink_to_fit()
-    { std::__shrink_to_fit(*this); }
+    {
+      if (this->_M_impl._M_finish._M_p == this->_M_impl._M_end_of_storage)
+	return false;
+      return std::__shrink_to_fit(*this);
+    }
 #endif
 
     void
Index: include/bits/allocator.h
===================================================================
--- include/bits/allocator.h	(revision 174814)
+++ include/bits/allocator.h	(working copy)
@@ -186,11 +186,12 @@
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
   template<typename _Tp>
     bool
-    __shrink_to_fit(_Tp& __v)
+    __shrink_to_fit(_Tp& __c)
     {
       __try
 	{
-	  _Tp(__v).swap(__v);
+	  _Tp(__make_move_if_noexcept_iterator(__c.begin()),
+	      __make_move_if_noexcept_iterator(__c.end())).swap(__c);
 	  return true;
 	}
       __catch(...)
Index: testsuite/21_strings/debug/shrink_to_fit.cc
===================================================================
--- testsuite/21_strings/debug/shrink_to_fit.cc	(revision 0)
+++ testsuite/21_strings/debug/shrink_to_fit.cc	(revision 0)
@@ -0,0 +1,39 @@
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-options "-std=gnu++0x" }
+// { dg-do run { xfail *-*-* } }
+
+#include <debug/string>
+
+void test01()
+{
+  using __gnu_debug::string;
+  string s;
+  s.reserve(2);
+  s.push_back('a');
+  string::iterator it = s.begin();
+  s.shrink_to_fit();
+  // Following line should assert
+  *it = 'z';
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/vector/debug/shrink_to_fit.cc
===================================================================
--- testsuite/23_containers/vector/debug/shrink_to_fit.cc	(revision 0)
+++ testsuite/23_containers/vector/debug/shrink_to_fit.cc	(revision 0)
@@ -0,0 +1,40 @@
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=gnu++0x" }
+// { dg-do run { xfail *-*-* } }
+
+#include <vector>
+
+void test01()
+{
+  using std::vector;
+  vector<int> v;
+  v.reserve(2);
+  v.push_back(0);
+  vector<int>::iterator it = v.begin();
+  v.shrink_to_fit();
+  // Following line should assert
+  *it = 1;
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
Index: testsuite/23_containers/deque/debug/shrink_to_fit.cc
===================================================================
--- testsuite/23_containers/deque/debug/shrink_to_fit.cc	(revision 0)
+++ testsuite/23_containers/deque/debug/shrink_to_fit.cc	(revision 0)
@@ -0,0 +1,45 @@
+// Copyright (C) 2011 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=gnu++0x" }
+// { dg-do run { xfail *-*-* } }
+
+#include <deque>
+
+void test01()
+{
+  using std::deque;
+  deque<int> d;
+  // Lets generate a hole at the begining of the deque:
+  d.push_back(0);
+  d.push_back(1);
+  d.pop_front();
+  deque<int>::iterator it;
+  do {
+    d.push_back(2);
+    it = d.begin();
+  } while (!d.shrink_to_fit());
+  // Following line should assert
+  *it = 2;
+}
+
+int main()
+{
+  test01();
+  return 0;
+}

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