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.

llvm-svn: 159918
This commit is contained in:
Howard Hinnant 2012-07-08 23:23:04 +00:00
parent d636ce5ec1
commit 598f702b04
2 changed files with 6 additions and 3 deletions

View File

@ -1966,6 +1966,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
} }
else else
{ {
value_type __tmp(_VSTD::forward<_Args>(__args)...);
iterator __b = __base::begin(); iterator __b = __base::begin();
iterator __bm1 = _VSTD::prev(__b); iterator __bm1 = _VSTD::prev(__b);
__alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__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(); ++__base::size();
if (__pos > 1) if (__pos > 1)
__b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b);
*__b = value_type(_VSTD::forward<_Args>(__args)...); *__b = _VSTD::move(__tmp);
} }
} }
else else
@ -1989,13 +1990,14 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args)
} }
else else
{ {
value_type __tmp(_VSTD::forward<_Args>(__args)...);
iterator __e = __base::end(); iterator __e = __base::end();
iterator __em1 = _VSTD::prev(__e); iterator __em1 = _VSTD::prev(__e);
__alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1));
++__base::size(); ++__base::size();
if (__de > 1) if (__de > 1)
__e = _VSTD::move_backward(__e - __de, __em1, __e); __e = _VSTD::move_backward(__e - __de, __em1, __e);
*--__e = value_type(_VSTD::forward<_Args>(__args)...); *--__e = _VSTD::move(__tmp);
} }
} }
return __base::begin() + __pos; return __base::begin() + __pos;

View File

@ -1681,8 +1681,9 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
} }
else else
{ {
value_type __tmp(_VSTD::forward<_Args>(__args)...);
__move_range(__p, this->__end_, __p + 1); __move_range(__p, this->__end_, __p + 1);
*__p = value_type(_VSTD::forward<_Args>(__args)...); *__p = _VSTD::move(__tmp);
} }
} }
else else