The exception recovery mechanism for the uninitialized_* algorithms did not work for iterators into discontiguous memory.

llvm-svn: 147343
This commit is contained in:
Howard Hinnant 2011-12-29 17:45:35 +00:00
parent 9e61291bf5
commit b34b48196c
2 changed files with 66 additions and 20 deletions

View File

@ -4751,6 +4751,8 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando
while (true) while (true)
{ {
__restart: __restart:
if (__nth == __last)
return;
difference_type __len = __last - __first; difference_type __len = __last - __first;
switch (__len) switch (__len)
{ {

View File

@ -3215,12 +3215,23 @@ template <class _InputIterator, class _ForwardIterator>
_ForwardIterator _ForwardIterator
uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r) uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
{ {
__destruct_n __d(0);
typedef typename iterator_traits<_ForwardIterator>::value_type value_type; typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
unique_ptr<value_type, __destruct_n&> __h(&*__r, __d); #ifndef _LIBCPP_NO_EXCEPTIONS
for (; __f != __l; ++__f, ++__r, __d.__incr((value_type*)0)) _ForwardIterator __s = __r;
::new(&*__r) value_type(*__f); try
__h.release(); {
#endif
for (; __f != __l; ++__f, ++__r)
::new(&*__r) value_type(*__f);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
for (; __s != __r; ++__s)
__s->~value_type();
throw;
}
#endif
return __r; return __r;
} }
@ -3228,12 +3239,23 @@ template <class _InputIterator, class _Size, class _ForwardIterator>
_ForwardIterator _ForwardIterator
uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r) uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)
{ {
__destruct_n __d(0);
typedef typename iterator_traits<_ForwardIterator>::value_type value_type; typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
unique_ptr<value_type, __destruct_n&> __h(&*__r, __d); #ifndef _LIBCPP_NO_EXCEPTIONS
for (; __n > 0; ++__f, ++__r, __d.__incr((value_type*)0), --__n) _ForwardIterator __s = __r;
::new(&*__r) value_type(*__f); try
__h.release(); {
#endif
for (; __n > 0; ++__f, ++__r, --__n)
::new(&*__r) value_type(*__f);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
for (; __s != __r; ++__s)
__s->~value_type();
throw;
}
#endif
return __r; return __r;
} }
@ -3241,24 +3263,46 @@ template <class _ForwardIterator, class _Tp>
void void
uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x) uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)
{ {
__destruct_n __d(0);
typedef typename iterator_traits<_ForwardIterator>::value_type value_type; typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
unique_ptr<value_type, __destruct_n&> __h(&*__f, __d); #ifndef _LIBCPP_NO_EXCEPTIONS
for (; __f != __l; ++__f, __d.__incr((value_type*)0)) _ForwardIterator __s = __f;
::new(&*__f) value_type(__x); try
__h.release(); {
#endif
for (; __f != __l; ++__f)
::new(&*__f) value_type(__x);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
for (; __s != __f; ++__s)
__s->~value_type();
throw;
}
#endif
} }
template <class _ForwardIterator, class _Size, class _Tp> template <class _ForwardIterator, class _Size, class _Tp>
_ForwardIterator _ForwardIterator
uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x) uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
{ {
__destruct_n __d(0);
typedef typename iterator_traits<_ForwardIterator>::value_type value_type; typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
unique_ptr<value_type, __destruct_n&> __h(&*__f, __d); #ifndef _LIBCPP_NO_EXCEPTIONS
for (; __n > 0; ++__f, --__n, __d.__incr((value_type*)0)) _ForwardIterator __s = __f;
::new(&*__f) value_type(__x); try
__h.release(); {
#endif
for (; __n > 0; ++__f, --__n)
::new(&*__f) value_type(__x);
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
for (; __s != __f; ++__s)
__s->~value_type();
throw;
}
#endif
return __f; return __f;
} }