From 8292d742700b1ed5b64aad40beef86ef39a6b202 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Thu, 29 Dec 2011 17:45:35 +0000 Subject: [PATCH] The exception recovery mechanism for the uninitialized_* algorithms did not work for iterators into discontiguous memory. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@147343 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/algorithm | 2 ++ include/memory | 84 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 66 insertions(+), 20 deletions(-) diff --git a/include/algorithm b/include/algorithm index 4679845e1..f9c6843a6 100644 --- a/include/algorithm +++ b/include/algorithm @@ -4751,6 +4751,8 @@ __nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Rando while (true) { __restart: + if (__nth == __last) + return; difference_type __len = __last - __first; switch (__len) { diff --git a/include/memory b/include/memory index 565aa7d5b..d15d81a2a 100644 --- a/include/memory +++ b/include/memory @@ -3215,12 +3215,23 @@ template _ForwardIterator uninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r) { - __destruct_n __d(0); typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - unique_ptr __h(&*__r, __d); - for (; __f != __l; ++__f, ++__r, __d.__incr((value_type*)0)) - ::new(&*__r) value_type(*__f); - __h.release(); +#ifndef _LIBCPP_NO_EXCEPTIONS + _ForwardIterator __s = __r; + try + { +#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; } @@ -3228,12 +3239,23 @@ template _ForwardIterator uninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r) { - __destruct_n __d(0); typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - unique_ptr __h(&*__r, __d); - for (; __n > 0; ++__f, ++__r, __d.__incr((value_type*)0), --__n) - ::new(&*__r) value_type(*__f); - __h.release(); +#ifndef _LIBCPP_NO_EXCEPTIONS + _ForwardIterator __s = __r; + try + { +#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; } @@ -3241,24 +3263,46 @@ template void uninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x) { - __destruct_n __d(0); typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - unique_ptr __h(&*__f, __d); - for (; __f != __l; ++__f, __d.__incr((value_type*)0)) - ::new(&*__f) value_type(__x); - __h.release(); +#ifndef _LIBCPP_NO_EXCEPTIONS + _ForwardIterator __s = __f; + try + { +#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 _ForwardIterator uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x) { - __destruct_n __d(0); typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - unique_ptr __h(&*__f, __d); - for (; __n > 0; ++__f, --__n, __d.__incr((value_type*)0)) - ::new(&*__f) value_type(__x); - __h.release(); +#ifndef _LIBCPP_NO_EXCEPTIONS + _ForwardIterator __s = __f; + try + { +#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; }