This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
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;
+}