Skip to content

Commit 12dce3b

Browse files
committed
[libc++] Destroy elements when exceptions are thrown in __construct_at_end
1 parent 0246f33 commit 12dce3b

File tree

5 files changed

+372
-33
lines changed

5 files changed

+372
-33
lines changed

libcxx/include/__memory/uninitialized_algorithms.h

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,12 @@ uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp&
125125
// uninitialized_fill_n
126126

127127
template <class _ValueType, class _ForwardIterator, class _Size, class _Tp>
128-
inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
128+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
129129
__uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) {
130130
_ForwardIterator __idx = __first;
131131
auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
132132
for (; __n > 0; ++__idx, (void)--__n)
133-
::new (static_cast<void*>(std::addressof(*__idx))) _ValueType(__x);
133+
std::__construct_at(std::addressof(*__idx), __x);
134134
__guard.__complete();
135135

136136
return __idx;
@@ -143,6 +143,20 @@ uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) {
143143
return std::__uninitialized_fill_n<_ValueType>(__first, __n, __x);
144144
}
145145

146+
// uninitialized_default_construct_n
147+
148+
template <class _ValueType, class _ForwardIterator, class _Size>
149+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
150+
__uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
151+
auto __idx = __first;
152+
auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
153+
for (; __n > 0; ++__idx, (void)--__n)
154+
std::__construct_at(std::addressof(*__idx));
155+
__guard.__complete();
156+
157+
return __idx;
158+
}
159+
146160
#if _LIBCPP_STD_VER >= 17
147161

148162
// uninitialized_default_construct
@@ -165,19 +179,6 @@ inline _LIBCPP_HIDE_FROM_ABI void uninitialized_default_construct(_ForwardIterat
165179
(void)std::__uninitialized_default_construct<_ValueType>(std::move(__first), std::move(__last));
166180
}
167181

168-
// uninitialized_default_construct_n
169-
170-
template <class _ValueType, class _ForwardIterator, class _Size>
171-
inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
172-
auto __idx = __first;
173-
auto __guard = std::__make_exception_guard([&] { std::__destroy(__first, __idx); });
174-
for (; __n > 0; ++__idx, (void)--__n)
175-
::new (static_cast<void*>(std::addressof(*__idx))) _ValueType;
176-
__guard.__complete();
177-
178-
return __idx;
179-
}
180-
181182
template <class _ForwardIterator, class _Size>
182183
inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
183184
using _ValueType = typename iterator_traits<_ForwardIterator>::value_type;

libcxx/include/__vector/vector.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -941,10 +941,7 @@ vector<_Tp, _Allocator>::__recommend(size_type __new_size) const {
941941
template <class _Tp, class _Allocator>
942942
_LIBCPP_CONSTEXPR_SINCE_CXX20 void vector<_Tp, _Allocator>::__construct_at_end(size_type __n) {
943943
_ConstructTransaction __tx(*this, __n);
944-
const_pointer __new_end = __tx.__new_end_;
945-
for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
946-
__alloc_traits::construct(this->__alloc_, std::__to_address(__pos));
947-
}
944+
__tx.__pos_ = std::__uninitialized_default_construct_n<_Tp>(this->__end_, __n);
948945
}
949946

950947
// Copy constructs __n objects starting at __end_ from __x
@@ -957,10 +954,7 @@ template <class _Tp, class _Allocator>
957954
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
958955
vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) {
959956
_ConstructTransaction __tx(*this, __n);
960-
const_pointer __new_end = __tx.__new_end_;
961-
for (pointer __pos = __tx.__pos_; __pos != __new_end; __tx.__pos_ = ++__pos) {
962-
__alloc_traits::construct(this->__alloc_, std::__to_address(__pos), __x);
963-
}
957+
__tx.__pos_ = std::__uninitialized_fill_n<_Tp>(this->__end_, __n, __x);
964958
}
965959

966960
template <class _Tp, class _Allocator>

0 commit comments

Comments
 (0)