re PR libstdc++/49561 ([C++0x] std::list::size complexity)
authorPaolo Carlini <paolo.carlini@oracle.com>
Tue, 4 Oct 2011 22:19:44 +0000 (22:19 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 4 Oct 2011 22:19:44 +0000 (22:19 +0000)
2011-10-04  Paolo Carlini  <paolo.carlini@oracle.com>

PR libstdc++/49561
* include/bits/stl_list.h (_List_base<>::_List_impl::_M_size):
Add in C++0x mode.
(_List_base<>::_List_impl, _List_base<>::_M_get_node,
_List_base<>::_M_put_node, _List_base<>::_List_base(_List_base&&),
list<>::size, list<>::swap, list<>::splice): Use it.
(operator==(const list<>&, const list<>&)): Rewrite in C++0x mode.
* include/bits/list.tcc (list<>::erase): Likewise.
(list<>::merge): Adjust in C++0x mode.
* testsuite/23_containers/list/requirements/dr438/assign_neg.cc:
Adjust dg-error line number.
* testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
Likewise.
* testsuite/23_containers/list/requirements/dr438/
constructor_1_neg.cc: Likewise.
* testsuite/23_containers/list/requirements/dr438/
constructor_2_neg.cc: Likewise.

From-SVN: r179528

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/list.tcc
libstdc++-v3/include/bits/stl_list.h
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc

index 2c17169ebca8cf8e8e1bd9ff6209d4ef9ef123c8..88d1d1b1188a99ef39eb46981cbc358a01f11f94 100644 (file)
@@ -1,3 +1,23 @@
+2011-10-04  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR libstdc++/49561
+       * include/bits/stl_list.h (_List_base<>::_List_impl::_M_size):
+       Add in C++0x mode.
+       (_List_base<>::_List_impl, _List_base<>::_M_get_node,
+       _List_base<>::_M_put_node, _List_base<>::_List_base(_List_base&&),
+       list<>::size, list<>::swap, list<>::splice): Use it.
+       (operator==(const list<>&, const list<>&)): Rewrite in C++0x mode.
+       * include/bits/list.tcc (list<>::erase): Likewise.
+       (list<>::merge): Adjust in C++0x mode.
+       * testsuite/23_containers/list/requirements/dr438/assign_neg.cc:
+       Adjust dg-error line number.
+       * testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
+       Likewise.
+       * testsuite/23_containers/list/requirements/dr438/
+       constructor_1_neg.cc: Likewise.
+       * testsuite/23_containers/list/requirements/dr438/
+       constructor_2_neg.cc: Likewise.
+
 2011-10-04  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * testsuite/20_util/bind/48698.cc (g): Fix return type, avoid -Wall
index 01c1bc6449590f0a1cf4861d3d21ea1c83b970bf..55156bbf062d1ab6f2558fdd16e52acb8a71b801 100644 (file)
@@ -67,8 +67,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     _M_clear()
     {
       typedef _List_node<_Tp>  _Node;
-      _Node* __cur = static_cast<_Node*>(this->_M_impl._M_node._M_next);
-      while (__cur != &this->_M_impl._M_node)
+      _Node* __cur = static_cast<_Node*>(_M_impl._M_node._M_next);
+      while (__cur != &_M_impl._M_node)
        {
          _Node* __tmp = __cur;
          __cur = static_cast<_Node*>(__cur->_M_next);
@@ -139,14 +139,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     list<_Tp, _Alloc>::
     resize(size_type __new_size)
     {
-      iterator __i = begin();
-      size_type __len = 0;
-      for (; __i != end() && __len < __new_size; ++__i, ++__len)
-        ;
-      if (__len == __new_size)
-        erase(__i, end());
-      else                          // __i == end()
-       _M_default_append(__new_size - __len);
+      if (__new_size > size())
+       _M_default_append(__new_size - size());
+      else if (__new_size < size())
+       {
+         iterator __i = begin();
+         std::advance(__i, __new_size);
+         erase(__i, end());
+       }
     }
 
   template<typename _Tp, typename _Alloc>
@@ -154,14 +154,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     list<_Tp, _Alloc>::
     resize(size_type __new_size, const value_type& __x)
     {
-      iterator __i = begin();
-      size_type __len = 0;
-      for (; __i != end() && __len < __new_size; ++__i, ++__len)
-        ;
-      if (__len == __new_size)
-        erase(__i, end());
-      else                          // __i == end()
-        insert(end(), __new_size - __len, __x);
+      if (__new_size > size())
+       insert(end(), __new_size - size(), __x);
+      else if (__new_size < size())
+       {
+         iterator __i = begin();
+         std::advance(__i, __new_size);
+         erase(__i, end());
+       }
     }
 #else
   template<typename _Tp, typename _Alloc>
@@ -312,6 +312,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
              ++__first1;
          if (__first2 != __last2)
            _M_transfer(__last1, __first2, __last2);
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+         this->_M_impl._M_size += __x.size();
+         __x._M_impl._M_size = 0;
+#endif
        }
     }
 
@@ -346,6 +351,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
                ++__first1;
            if (__first2 != __last2)
              _M_transfer(__last1, __first2, __last2);
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+           this->_M_impl._M_size += __x.size();
+           __x._M_impl._M_size = 0;
+#endif
          }
       }
 
index 91e39f3256c7211f1e66df17fd4da92c7053f77c..56ee2fbfd2e4d098fcd0e70254b1e85f6581ab08 100644 (file)
@@ -306,22 +306,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
 
-      struct _List_impl 
+      struct _List_impl
       : public _Node_alloc_type
       {
        __detail::_List_node_base _M_node;
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+       size_t                    _M_size;
+#endif
+
        _List_impl()
        : _Node_alloc_type(), _M_node()
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+       , _M_size(0)
+#endif
        { }
 
        _List_impl(const _Node_alloc_type& __a)
        : _Node_alloc_type(__a), _M_node()
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+       , _M_size(0)
+#endif
        { }
 
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
        _List_impl(_Node_alloc_type&& __a)
-       : _Node_alloc_type(std::move(__a)), _M_node()
+       : _Node_alloc_type(std::move(__a)), _M_node(), _M_size(0)
        { }
 #endif
       };
@@ -330,22 +340,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
       _List_node<_Tp>*
       _M_get_node()
-      { return _M_impl._Node_alloc_type::allocate(1); }
-      
+      {
+       _List_node<_Tp>* __tmp = _M_impl._Node_alloc_type::allocate(1);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+       ++_M_impl._M_size;
+#endif 
+       return __tmp;
+      }
+
       void
       _M_put_node(_List_node<_Tp>* __p)
-      { _M_impl._Node_alloc_type::deallocate(__p, 1); }
+      {
+       _M_impl._Node_alloc_type::deallocate(__p, 1);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+       --_M_impl._M_size;
+#endif
+      }
       
   public:
       typedef _Alloc allocator_type;
 
       _Node_alloc_type&
       _M_get_Node_allocator() _GLIBCXX_NOEXCEPT
-      { return *static_cast<_Node_alloc_type*>(&this->_M_impl); }
+      { return *static_cast<_Node_alloc_type*>(&_M_impl); }
 
       const _Node_alloc_type&
       _M_get_Node_allocator() const _GLIBCXX_NOEXCEPT
-      { return *static_cast<const _Node_alloc_type*>(&this->_M_impl); }
+      { return *static_cast<const _Node_alloc_type*>(&_M_impl); }
 
       _Tp_alloc_type
       _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT
@@ -368,8 +389,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       : _M_impl(std::move(__x._M_get_Node_allocator()))
       {
        _M_init();
-       __detail::_List_node_base::swap(this->_M_impl._M_node, 
-                                       __x._M_impl._M_node);   
+       __detail::_List_node_base::swap(_M_impl._M_node, __x._M_impl._M_node);
+       std::swap(_M_impl._M_size, __x._M_impl._M_size);
       }
 #endif
 
@@ -851,7 +872,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       /**  Returns the number of elements in the %list.  */
       size_type
       size() const _GLIBCXX_NOEXCEPT
-      { return std::distance(begin(), end()); }
+      {
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+       return this->_M_impl._M_size;
+#else
+       return std::distance(begin(), end());
+#endif
+      }
 
       /**  Returns the size() of the largest possible %list.  */
       size_type
@@ -1186,6 +1213,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       {
        __detail::_List_node_base::swap(this->_M_impl._M_node, 
                                        __x._M_impl._M_node);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+       std::swap(this->_M_impl._M_size, __x._M_impl._M_size);
+#endif
 
        // _GLIBCXX_RESOLVE_LIB_DEFECTS
        // 431. Swapping containers with unequal allocators.
@@ -1230,6 +1260,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            _M_check_equal_allocators(__x);
 
            this->_M_transfer(__position, __x.begin(), __x.end());
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+           this->_M_impl._M_size += __x.size();
+           __x._M_impl._M_size = 0;
+#endif
          }
       }
 
@@ -1261,7 +1296,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          return;
 
        if (this != &__x)
-         _M_check_equal_allocators(__x);
+         {
+           _M_check_equal_allocators(__x);
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+           ++this->_M_impl._M_size;
+           --__x._M_impl._M_size;
+#endif
+         }
 
        this->_M_transfer(__position, __i, __j);
       }
@@ -1296,7 +1338,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        if (__first != __last)
          {
            if (this != &__x)
-             _M_check_equal_allocators(__x);
+             {
+               _M_check_equal_allocators(__x);
+
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+               const size_type __size = std::distance(__first, __last);
+               this->_M_impl._M_size += __size;
+               __x._M_impl._M_size -= __size;
+#endif
+             }
 
            this->_M_transfer(__position, __first, __last);
          }
@@ -1571,6 +1621,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     inline bool
     operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
     {
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+      return (__x.size() == __y.size()
+             && std::equal(__x.begin(), __x.end(), __y.begin()));
+#else
       typedef typename list<_Tp, _Alloc>::const_iterator const_iterator;
       const_iterator __end1 = __x.end();
       const_iterator __end2 = __y.end();
@@ -1583,6 +1637,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
          ++__i2;
        }
       return __i1 == __end1 && __i2 == __end2;
+#endif
     }
 
   /**
index f53082d1aa1331fc94451d28a5f1d0a8cf74bb8a..974821f0e529e82a5b04c38eace12cad6f211230 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1499 }
+// { dg-error "no matching" "" { target *-*-* } 1549 }
 
 #include <list>
 
index f0af9715138cd8f4e67232920b1104054334826c..6683e78062d294d726bb563e1e7f371153776dee 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1455 }
+// { dg-error "no matching" "" { target *-*-* } 1505 }
 
 #include <list>
 
index 168d592361d06e5d89b333add531dab5e4379494..f3e70098ea0f7c3c6259038711977e1d8f398790 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1455 }
+// { dg-error "no matching" "" { target *-*-* } 1505 }
 
 #include <list>
 #include <utility>
index 32bfd53e7c1bb11df52aa6ce0c9bd0d65a536e8d..7e19c4205dc8ca88d38dfb6fb39be6e7cecfeef8 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1455 }
+// { dg-error "no matching" "" { target *-*-* } 1505 }
 
 #include <list>