Fix std::deque move construction with non-equal allocators.
authorJonathan Wakely <jwakely@redhat.com>
Mon, 10 Nov 2014 22:44:07 +0000 (22:44 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 10 Nov 2014 22:44:07 +0000 (22:44 +0000)
* include/bits/stl_deque.h (_Deque_base::_Deque_base(_Deque_base&&)):
Dispatch according to whether allocators are always equal.
(_Deque_base::_M_move_impl()): Implement move-from state.
* testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: Fix
dg-error line number.
* testsuite/23_containers/deque/requirements/dr438/
constructor_1_neg.cc: Likewise.
* testsuite/23_containers/deque/requirements/dr438/
constructor_2_neg.cc: Likewise.
* testsuite/23_containers/deque/requirements/dr438/insert_neg.cc:
Likewise.

From-SVN: r217322

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

index 33aa6f03041605cb1a38a5a9d257cbd44806ea06..0f33b7aa5ad5e05dba33bca471324e3ae7328ff3 100644 (file)
@@ -1,3 +1,17 @@
+2014-11-10  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/bits/stl_deque.h (_Deque_base::_Deque_base(_Deque_base&&)):
+       Dispatch according to whether allocators are always equal.
+       (_Deque_base::_M_move_impl()): Implement move-from state.
+       * testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: Fix
+       dg-error line number.
+       * testsuite/23_containers/deque/requirements/dr438/
+       constructor_1_neg.cc: Likewise.
+       * testsuite/23_containers/deque/requirements/dr438/
+       constructor_2_neg.cc: Likewise.
+       * testsuite/23_containers/deque/requirements/dr438/insert_neg.cc:
+       Likewise.
+
 2014-11-10  François Dumont  <fdumont@gcc.gnu.org>
 
        Major maintenance patch of the profile mode.
index d50d3c90991e7f5eebbdfac0b3ccb44fa82ab673..c0052b39b04d83d4810a185c351a0d3325263df5 100644 (file)
@@ -502,14 +502,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       { /* Caller must initialize map. */ }
 
 #if __cplusplus >= 201103L
-      _Deque_base(_Deque_base&& __x)
-      : _M_impl(__x._M_get_Tp_allocator())
+      _Deque_base(_Deque_base&& __x, false_type)
+      : _M_impl(__x._M_move_impl())
+      { }
+
+      _Deque_base(_Deque_base&& __x, true_type)
+      : _M_impl(std::move(__x._M_get_Tp_allocator()))
       {
        _M_initialize_map(0);
        if (__x._M_impl._M_map)
          this->_M_impl._M_swap_data(__x._M_impl);
       }
 
+      _Deque_base(_Deque_base&& __x)
+      : _Deque_base(std::move(__x),
+                   __gnu_cxx::__allocator_always_compares_equal<_Alloc>{})
+      { }
+
       _Deque_base(_Deque_base&& __x, const allocator_type& __a, size_type __n)
       : _M_impl(__a)
       {
@@ -555,18 +564,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        { }
 
 #if __cplusplus >= 201103L
-       _Deque_impl(_Tp_alloc_type&& __a) _GLIBCXX_NOEXCEPT
+       _Deque_impl(_Deque_impl&&) = default;
+
+       _Deque_impl(_Tp_alloc_type&& __a) noexcept
        : _Tp_alloc_type(std::move(__a)), _M_map(), _M_map_size(0),
          _M_start(), _M_finish()
        { }
 #endif
 
-       void _M_swap_data(_Deque_impl& __x)
+       void _M_swap_data(_Deque_impl& __x) _GLIBCXX_NOEXCEPT
        {
-         std::swap(this->_M_start, __x._M_start);
-         std::swap(this->_M_finish, __x._M_finish);
-         std::swap(this->_M_map, __x._M_map);
-         std::swap(this->_M_map_size, __x._M_map_size);
+         using std::swap;
+         swap(this->_M_start, __x._M_start);
+         swap(this->_M_finish, __x._M_finish);
+         swap(this->_M_map, __x._M_map);
+         swap(this->_M_map_size, __x._M_map_size);
        }
       };
 
@@ -618,6 +630,28 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       enum { _S_initial_map_size = 8 };
 
       _Deque_impl _M_impl;
+
+#if __cplusplus >= 201103L
+    private:
+      _Deque_impl
+      _M_move_impl()
+      {
+       if (!_M_impl._M_map)
+         return std::move(_M_impl);
+
+       // Create a copy of the current allocator.
+       _Tp_alloc_type __alloc{_M_get_Tp_allocator()};
+       // Put that copy in a moved-from state.
+       _Tp_alloc_type __unused __attribute((__unused__)) {std::move(__alloc)};
+       // Create an empty map that allocates using the moved-from allocator.
+       _Deque_base __empty{__alloc};
+       // Now safe to modify current allocator and perform non-throwing swaps.
+       _Deque_impl __ret{std::move(_M_get_Tp_allocator())};
+       _M_impl._M_swap_data(__ret);
+       _M_impl._M_swap_data(__empty._M_impl);
+       return __ret;
+      }
+#endif
     };
 
   template<typename _Tp, typename _Alloc>
index 8092ead6d41df1f2f30f4044d9c791585fb9cf8b..b38f3ae45c33941590f7946a48f5bed467612521 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1859 }
+// { dg-error "no matching" "" { target *-*-* } 1881 }
 
 #include <deque>
 
index 4abdf4682bea8c85e05238f56292377432e6d910..a30029a0395a78500941a3d0b6db610fad1921f7 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1792 }
+// { dg-error "no matching" "" { target *-*-* } 1814 }
 
 #include <deque>
 
index 61bce4eb049a1628e3254624c6f58611ec841fa7..02eba79b9cf4da89c657af17afd2b19aa3fbc485 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1792 }
+// { dg-error "no matching" "" { target *-*-* } 1814 }
 
 #include <deque>
 #include <utility>
index a0ca00caf8ad67ab5aca908fafd23eac3a997f33..8c1dd2e949f65dbb81fc954a5cc2f1cc189f730d 100644 (file)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1943 }
+// { dg-error "no matching" "" { target *-*-* } 1965 }
 
 #include <deque>