stl_list.h (_M_resize_pos(size_type&)): Declare.
authorJonathan Wakely <jwakely@redhat.com>
Tue, 19 May 2015 22:24:50 +0000 (23:24 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 19 May 2015 22:24:50 +0000 (23:24 +0100)
* include/bits/stl_list.h (_M_resize_pos(size_type&)): Declare.
(operator==(const list&, const list&)): If size() is O(1) compare
sizes before comparing each element.
* include/bits/list.tcc (list::_M_resize_pos(size_type&)): Define.
(list::resize): Use _M_resize_pos.

From-SVN: r223416

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/list.tcc
libstdc++-v3/include/bits/stl_list.h

index 0cdd178d9eef83bec3eac4eb7fb9d1f33346b43f..6c5964af75ad88cdb6c4d89d330642424c3fc9c1 100644 (file)
@@ -1,3 +1,11 @@
+2015-05-19  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/bits/stl_list.h (_M_resize_pos(size_type&)): Declare.
+       (operator==(const list&, const list&)): If size() is O(1) compare
+       sizes before comparing each element.
+       * include/bits/list.tcc (list::_M_resize_pos(size_type&)): Define.
+       (list::resize): Use _M_resize_pos.
+
 2015-05-19  François Dumont  <fdumont@gcc.gnu.org>
 
        * testsuite/23_containers/unordered_map/cons/66055.cc: Add constructor
index a9c8a550b4ac46a2e377c307795e6f9e0b38f88b..c5d2ab4e9d1f174fcc1d2f077d645c5a5d49994b 100644 (file)
@@ -157,6 +157,52 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       return __ret;
     }
 
+  // Return a const_iterator indicating the position to start inserting or
+  // erasing elements (depending whether the list is growing or shrinking),
+  // and set __new_size to the number of new elements that must be appended.
+  // Equivalent to the following, but performed optimally:
+  // if (__new_size < size()) {
+  //   __new_size = 0;
+  //   return std::next(begin(), __new_size);
+  // } else {
+  //   __newsize -= size();
+  //   return end();
+  // }
+  template<typename _Tp, typename _Alloc>
+    typename list<_Tp, _Alloc>::const_iterator
+    list<_Tp, _Alloc>::
+    _M_resize_pos(size_type& __new_size) const
+    {
+      const_iterator __i;
+#if _GLIBCXX_USE_CXX11_ABI
+      const size_type __len = size();
+      if (__new_size < __len)
+       {
+         if (__new_size <= __len / 2)
+           {
+             __i = begin();
+             std::advance(__i, __new_size);
+           }
+         else
+           {
+             __i = end();
+             ptrdiff_t __num_erase = __len - __new_size;
+             std::advance(__i, -__num_erase);
+           }
+         __new_size = 0;
+         return __i;
+       }
+      else
+       __i = end();
+#else
+      size_type __len = 0;
+      for (__i = begin(); __i != end() && __len < __new_size; ++__i, ++__len)
+        ;
+#endif
+      __new_size -= __len;
+      return __i;
+    }
+
 #if __cplusplus >= 201103L
   template<typename _Tp, typename _Alloc>
     void
@@ -182,14 +228,11 @@ _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)
+      const_iterator __i = _M_resize_pos(__new_size);
+      if (__new_size)
+       _M_default_append(__new_size);
+      else
         erase(__i, end());
-      else                          // __i == end()
-       _M_default_append(__new_size - __len);
     }
 
   template<typename _Tp, typename _Alloc>
@@ -197,14 +240,11 @@ _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)
+      const_iterator __i = _M_resize_pos(__new_size);
+      if (__new_size)
+        insert(end(), __new_size, __x);
+      else
         erase(__i, end());
-      else                          // __i == end()
-        insert(end(), __new_size - __len, __x);
     }
 #else
   template<typename _Tp, typename _Alloc>
@@ -212,14 +252,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     list<_Tp, _Alloc>::
     resize(size_type __new_size, 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);
+      const_iterator __i = _M_resize_pos(__new_size);
+      if (__new_size)
+        insert(end(), __new_size, __x);
+      else
+        erase(__i._M_const_cast(), end());
     }
 #endif
 
index 3401e5b4d2552fd2f89b77bc5b0cb9df4737aa70..a26859ec7faaaed00ec8679346e1a1895d531d21 100644 (file)
@@ -1789,6 +1789,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
            _S_do_it(_M_get_Node_allocator(), __x._M_get_Node_allocator()))
          __builtin_abort();
       }
+
+      // Used to implement resize.
+      const_iterator
+      _M_resize_pos(size_type& __new_size) const;
     };
 _GLIBCXX_END_NAMESPACE_CXX11
 
@@ -1806,6 +1810,11 @@ _GLIBCXX_END_NAMESPACE_CXX11
     inline bool
     operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y)
     {
+#if _GLIBCXX_USE_CXX11_ABI
+      if (__x.size() != __y.size())
+       return false;
+#endif
+
       typedef typename list<_Tp, _Alloc>::const_iterator const_iterator;
       const_iterator __end1 = __x.end();
       const_iterator __end2 = __y.end();