stl_vector.h (push_back(const value_type&)): Forward to _M_realloc_insert.
authorFrançois Dumont <fdumont@gcc.gnu.org>
Mon, 11 Jul 2016 20:17:56 +0000 (20:17 +0000)
committerFrançois Dumont <fdumont@gcc.gnu.org>
Mon, 11 Jul 2016 20:17:56 +0000 (20:17 +0000)
2016-07-11  François Dumont  <fdumont@gcc.gnu.org>

* include/bits/stl_vector.h (push_back(const value_type&)): Forward
to _M_realloc_insert.
(insert(const_iterator, value_type&&)): Forward to _M_insert_rval.
(_M_realloc_insert): Declare new function.
(_M_emplace_back_aux): Remove definition.
* include/bits/vector.tcc (emplace_back(_Args...)):
Use _M_realloc_insert.
(insert(const_iterator, const value_type&)): Likewise.
(_M_insert_rval, _M_emplace_aux): Likewise.
(_M_emplace_back_aux): Remove declaration.
(_M_realloc_insert): Define.
* testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc:
Adjust expected results for emplacing an lvalue with reallocation.

From-SVN: r238226

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/bits/vector.tcc
libstdc++-v3/testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc

index 0aee6800828bc3c967cc8a44b9e2eb21609d7000..1d0abe1c242ab193cc6a6913ac300306f061cc4c 100644 (file)
@@ -1,3 +1,19 @@
+2016-07-11  François Dumont  <fdumont@gcc.gnu.org>
+
+       * include/bits/stl_vector.h (push_back(const value_type&)): Forward
+       to _M_realloc_insert.
+       (insert(const_iterator, value_type&&)): Forward to _M_insert_rval.
+       (_M_realloc_insert): Declare new function.
+       (_M_emplace_back_aux): Remove definition.
+       * include/bits/vector.tcc (emplace_back(_Args...)):
+       Use _M_realloc_insert.
+       (insert(const_iterator, const value_type&)): Likewise.
+       (_M_insert_rval, _M_emplace_aux): Likewise.
+       (_M_emplace_back_aux): Remove declaration.
+       (_M_realloc_insert): Define.
+       * testsuite/23_containers/vector/modifiers/insert_vs_emplace.cc:
+       Adjust expected results for emplacing an lvalue with reallocation.
+
 2016-07-10  Ville Voutilainen  <ville.voutilainen@gmail.com>
 
        Implement std::optional.
index 8e8aa7cf0d1d90e381ee40b5555902924b08d840..85abf4a3cc0642b6f416910353c48b571ebcefe6 100644 (file)
@@ -946,11 +946,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            ++this->_M_impl._M_finish;
          }
        else
-#if __cplusplus >= 201103L
-         _M_emplace_back_aux(__x);
-#else
-         _M_insert_aux(end(), __x);
-#endif
+         _M_realloc_insert(end(), __x);
       }
 
 #if __cplusplus >= 201103L
@@ -1436,6 +1432,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       // Called by insert(p,x)
       void
       _M_insert_aux(iterator __position, const value_type& __x);
+
+      void
+      _M_realloc_insert(iterator __position, const value_type& __x);
 #else
       // A value_type object constructed with _Alloc_traits::construct()
       // and destroyed with _Alloc_traits::destroy().
@@ -1469,16 +1468,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        void
        _M_insert_aux(iterator __position, _Arg&& __arg);
 
+      template<typename... _Args>
+       void
+       _M_realloc_insert(iterator __position, _Args&&... __args);
+
       // Either move-construct at the end, or forward to _M_insert_aux.
       iterator
       _M_insert_rval(const_iterator __position, value_type&& __v);
 
-      // Called by push_back(x) and emplace_back(args) when they need to
-      // reallocate.
-      template<typename... _Args>
-       void
-       _M_emplace_back_aux(_Args&&... __args);
-
       // Try to emplace at the end, otherwise forward to _M_insert_aux.
       template<typename... _Args>
        iterator
index dd0d288eaab82274a6df20751214179f1c5e4fbb..9717b74a9781f8f39bc6247060586e1641167159 100644 (file)
@@ -98,7 +98,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
            ++this->_M_impl._M_finish;
          }
        else
-         _M_emplace_back_aux(std::forward<_Args>(__args)...);
+         _M_realloc_insert(end(), std::forward<_Args>(__args)...);
       }
 #endif
 
@@ -112,29 +112,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #endif
     {
       const size_type __n = __position - begin();
-      if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
-         && __position == end())
-       {
-         _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x);
-         ++this->_M_impl._M_finish;
-       }
-      else
-       {
+      if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+       if (__position == end())
+         {
+           _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+                                    __x);
+           ++this->_M_impl._M_finish;
+         }
+       else
+         {
 #if __cplusplus >= 201103L
-         const auto __pos = begin() + (__position - cbegin());
-         if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
-           {
-             // __x could be an existing element of this vector, so make a
-             // copy of it before _M_insert_aux moves elements around.
-             _Temporary_value __x_copy(this, __x);
-             _M_insert_aux(__pos, std::move(__x_copy._M_val()));
-           }
-         else
-           _M_insert_aux(__pos, __x);
+           const auto __pos = begin() + (__position - cbegin());
+           // __x could be an existing element of this vector, so make a
+           // copy of it before _M_insert_aux moves elements around.
+           _Temporary_value __x_copy(this, __x);
+           _M_insert_aux(__pos, std::move(__x_copy._M_val()));
 #else
            _M_insert_aux(__position, __x);
 #endif
-       }
+         }
+      else
+#if __cplusplus >= 201103L
+       _M_realloc_insert(begin() + (__position - cbegin()), __x);
+#else
+       _M_realloc_insert(__position, __x);
+#endif
+
       return iterator(this->_M_impl._M_start + __n);
     }
 
@@ -304,15 +307,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     _M_insert_rval(const_iterator __position, value_type&& __v) -> iterator
     {
       const auto __n = __position - cbegin();
-      if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
-         && __position == cend())
-       {
-         _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
-                                  std::move(__v));
-         ++this->_M_impl._M_finish;
-       }
+      if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+       if (__position == cend())
+         {
+           _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+                                    std::move(__v));
+           ++this->_M_impl._M_finish;
+         }
+       else
+         _M_insert_aux(begin() + __n, std::move(__v));
       else
-       _M_insert_aux(begin() + __n, std::move(__v));
+       _M_realloc_insert(begin() + __n, std::move(__v));
+
       return iterator(this->_M_impl._M_start + __n);
     }
 
@@ -324,16 +330,24 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       -> iterator
       {
        const auto __n = __position - cbegin();
-       if (__position == cend())
-         emplace_back(std::forward<_Args>(__args)...);
+       if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
+         if (__position == cend())
+           {
+             _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+                                      std::forward<_Args>(__args)...);
+             ++this->_M_impl._M_finish;
+           }
+         else
+           {
+             // We need to construct a temporary because something in __args...
+             // could alias one of the elements of the container and so we
+             // need to use it before _M_insert_aux moves elements around.
+             _Temporary_value __tmp(this, std::forward<_Args>(__args)...);
+             _M_insert_aux(begin() + __n, std::move(__tmp._M_val()));
+           }
        else
-         {
-           // We need to construct a temporary because something in __args...
-           // could alias one of the elements of the container and so we
-           // need to use it before _M_insert_aux moves elements around.
-           _Temporary_value __tmp(this, std::forward<_Args>(__args)...);
-           _M_insert_aux(begin() + __n, std::move(__tmp._M_val()));
-         }
+         _M_realloc_insert(begin() + __n, std::forward<_Args>(__args)...);
+
        return iterator(this->_M_impl._M_start + __n);
       }
 
@@ -349,78 +363,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     _M_insert_aux(iterator __position, const _Tp& __x)
 #endif
     {
-      if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
-       {
-         _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
-                                  _GLIBCXX_MOVE(*(this->_M_impl._M_finish
-                                                  - 1)));
-         ++this->_M_impl._M_finish;
+      _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
+                              _GLIBCXX_MOVE(*(this->_M_impl._M_finish
+                                              - 1)));
+      ++this->_M_impl._M_finish;
 #if __cplusplus < 201103L
-         _Tp __x_copy = __x;
+      _Tp __x_copy = __x;
 #endif
-         _GLIBCXX_MOVE_BACKWARD3(__position.base(),
-                                 this->_M_impl._M_finish - 2,
-                                 this->_M_impl._M_finish - 1);
+      _GLIBCXX_MOVE_BACKWARD3(__position.base(),
+                             this->_M_impl._M_finish - 2,
+                             this->_M_impl._M_finish - 1);
 #if __cplusplus < 201103L
-         *__position = __x_copy;
-#else
-         *__position = std::forward<_Arg>(__arg);
-#endif
-       }
-      else
-       {
-         const size_type __len =
-           _M_check_len(size_type(1), "vector::_M_insert_aux");
-         const size_type __elems_before = __position - begin();
-         pointer __new_start(this->_M_allocate(__len));
-         pointer __new_finish(__new_start);
-         __try
-           {
-             // The order of the three operations is dictated by the C++11
-             // case, where the moves could alter a new element belonging
-             // to the existing vector.  This is an issue only for callers
-             // taking the element by lvalue ref (see last bullet of C++11
-             // [res.on.arguments]).
-             _Alloc_traits::construct(this->_M_impl,
-                                      __new_start + __elems_before,
-#if __cplusplus >= 201103L
-                                      std::forward<_Arg>(__arg));
+      *__position = __x_copy;
 #else
-                                      __x);
+      *__position = std::forward<_Arg>(__arg);
 #endif
-             __new_finish = pointer();
-
-             __new_finish
-               = std::__uninitialized_move_if_noexcept_a
-               (this->_M_impl._M_start, __position.base(),
-                __new_start, _M_get_Tp_allocator());
-
-             ++__new_finish;
-
-             __new_finish
-               = std::__uninitialized_move_if_noexcept_a
-               (__position.base(), this->_M_impl._M_finish,
-                __new_finish, _M_get_Tp_allocator());
-           }
-          __catch(...)
-           {
-             if (!__new_finish)
-               _Alloc_traits::destroy(this->_M_impl,
-                                      __new_start + __elems_before);
-             else
-               std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
-             _M_deallocate(__new_start, __len);
-             __throw_exception_again;
-           }
-         std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
-                       _M_get_Tp_allocator());
-         _M_deallocate(this->_M_impl._M_start,
-                       this->_M_impl._M_end_of_storage
-                       - this->_M_impl._M_start);
-         this->_M_impl._M_start = __new_start;
-         this->_M_impl._M_finish = __new_finish;
-         this->_M_impl._M_end_of_storage = __new_start + __len;
-       }
     }
 
 #if __cplusplus >= 201103L
@@ -428,44 +385,66 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
     template<typename... _Args>
       void
       vector<_Tp, _Alloc>::
-      _M_emplace_back_aux(_Args&&... __args)
-      {
-       const size_type __len =
-         _M_check_len(size_type(1), "vector::_M_emplace_back_aux");
-       pointer __new_start(this->_M_allocate(__len));
-       pointer __new_finish(__new_start);
-       __try
-         {
-           _Alloc_traits::construct(this->_M_impl, __new_start + size(),
-                                    std::forward<_Args>(__args)...);
-           __new_finish = pointer();
+      _M_realloc_insert(iterator __position, _Args&&... __args)
+#else
+  template<typename _Tp, typename _Alloc>
+    void
+    vector<_Tp, _Alloc>::
+    _M_realloc_insert(iterator __position, const _Tp& __x)
+#endif
+    {
+      const size_type __len =
+       _M_check_len(size_type(1), "vector::_M_realloc_insert");
+      const size_type __elems_before = __position - begin();
+      pointer __new_start(this->_M_allocate(__len));
+      pointer __new_finish(__new_start);
+      __try
+       {
+         // The order of the three operations is dictated by the C++11
+         // case, where the moves could alter a new element belonging
+         // to the existing vector.  This is an issue only for callers
+         // taking the element by lvalue ref (see last bullet of C++11
+         // [res.on.arguments]).
+         _Alloc_traits::construct(this->_M_impl,
+                                  __new_start + __elems_before,
+#if __cplusplus >= 201103L
+                                  std::forward<_Args>(__args)...);
+#else
+                                  __x);
+#endif
+         __new_finish = pointer();
 
-           __new_finish
-             = std::__uninitialized_move_if_noexcept_a
-             (this->_M_impl._M_start, this->_M_impl._M_finish,
-              __new_start, _M_get_Tp_allocator());
+         __new_finish
+           = std::__uninitialized_move_if_noexcept_a
+           (this->_M_impl._M_start, __position.base(),
+            __new_start, _M_get_Tp_allocator());
 
-           ++__new_finish;
-         }
-       __catch(...)
-         {
-           if (!__new_finish)
-             _Alloc_traits::destroy(this->_M_impl, __new_start + size());
-           else
-             std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
-           _M_deallocate(__new_start, __len);
-           __throw_exception_again;
-         }
-       std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
-                     _M_get_Tp_allocator());
-       _M_deallocate(this->_M_impl._M_start,
-                     this->_M_impl._M_end_of_storage
-                     - this->_M_impl._M_start);
-       this->_M_impl._M_start = __new_start;
-       this->_M_impl._M_finish = __new_finish;
-       this->_M_impl._M_end_of_storage = __new_start + __len;
-      }
-#endif
+         ++__new_finish;
+
+         __new_finish
+           = std::__uninitialized_move_if_noexcept_a
+           (__position.base(), this->_M_impl._M_finish,
+            __new_finish, _M_get_Tp_allocator());
+       }
+      __catch(...)
+       {
+         if (!__new_finish)
+           _Alloc_traits::destroy(this->_M_impl,
+                                  __new_start + __elems_before);
+         else
+           std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
+         _M_deallocate(__new_start, __len);
+         __throw_exception_again;
+       }
+      std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
+                   _M_get_Tp_allocator());
+      _M_deallocate(this->_M_impl._M_start,
+                   this->_M_impl._M_end_of_storage
+                   - this->_M_impl._M_start);
+      this->_M_impl._M_start = __new_start;
+      this->_M_impl._M_finish = __new_finish;
+      this->_M_impl._M_end_of_storage = __new_start + __len;
+    }
 
   template<typename _Tp, typename _Alloc>
     void
@@ -520,7 +499,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
              pointer __new_finish(__new_start);
              __try
                {
-                 // See _M_insert_aux above.
+                 // See _M_realloc_insert above.
                  std::__uninitialized_fill_n_a(__new_start + __elems_before,
                                                __n, __x,
                                                _M_get_Tp_allocator());
index 1b461240592c77fc0b3fef71e828abf2cfc53176..39a3f031b461a705eba5020b1ed5d9b7ebe6e5de 100644 (file)
@@ -223,8 +223,7 @@ test03()
 void
 test04()
 {
-  const X::special expected_ins{ 0, 3, 1, 0, 3, 0 };
-  const X::special expected_emp{ 0, 4, 1, 0, 4, 0 };
+  const X::special expected{ 0, 3, 1, 0, 3, 0 };
   X::special ins, emp;
   {
     std::vector<X> v;
@@ -254,8 +253,8 @@ test04()
     // std::cout << "----\n";
     emp = X::sp;
   }
-  VERIFY( ins == expected_ins );
-  VERIFY( emp == expected_emp );
+  VERIFY( ins == emp );
+  VERIFY( ins == expected );
 }
 
 // insert vs emplace xvalue reallocation