From a58402abb97a84f34c4fb2e6e0015080c13e50ab Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Sun, 8 Jul 2012 23:23:04 +0000 Subject: [PATCH] Change emplace for vector and deque to create the temporary (when necessary) before any changes to the container are made. Nikolay Ivchenkov deserves the credit for pushing this problem and the solution for it. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@159918 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/deque | 6 ++++-- include/vector | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/deque b/include/deque index e65acfc8..b86d77f9 100644 --- a/include/deque +++ b/include/deque @@ -1966,6 +1966,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) } else { + value_type __tmp(_VSTD::forward<_Args>(__args)...); iterator __b = __base::begin(); iterator __bm1 = _VSTD::prev(__b); __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); @@ -1973,7 +1974,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) ++__base::size(); if (__pos > 1) __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); - *__b = value_type(_VSTD::forward<_Args>(__args)...); + *__b = _VSTD::move(__tmp); } } else @@ -1989,13 +1990,14 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) } else { + value_type __tmp(_VSTD::forward<_Args>(__args)...); iterator __e = __base::end(); iterator __em1 = _VSTD::prev(__e); __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); ++__base::size(); if (__de > 1) __e = _VSTD::move_backward(__e - __de, __em1, __e); - *--__e = value_type(_VSTD::forward<_Args>(__args)...); + *--__e = _VSTD::move(__tmp); } } return __base::begin() + __pos; diff --git a/include/vector b/include/vector index 0d5b6b8b..04a23ab7 100644 --- a/include/vector +++ b/include/vector @@ -1681,8 +1681,9 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) } else { + value_type __tmp(_VSTD::forward<_Args>(__args)...); __move_range(__p, this->__end_, __p + 1); - *__p = value_type(_VSTD::forward<_Args>(__args)...); + *__p = _VSTD::move(__tmp); } } else