@@ -297,6 +297,7 @@ erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
297297#include < __utility/forward.h>
298298#include < __utility/move.h>
299299#include < __utility/swap.h>
300+ #include < __utility/transaction.h>
300301#include < climits>
301302#include < cstdlib>
302303#include < cstring>
@@ -425,18 +426,27 @@ public:
425426 value_type,
426427 typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0 );
427428
428- _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
429- ~vector ()
430- {
431- __annotate_delete ();
432- std::__debug_db_erase_c (this );
429+ private:
430+ class __destroy_vector {
431+ public:
432+ _LIBCPP_CONSTEXPR __destroy_vector (vector& __vec) : __vec_(__vec) {}
433433
434- if (this ->__begin_ != nullptr )
435- {
436- __clear ();
437- __alloc_traits::deallocate (__alloc (), this ->__begin_ , capacity ());
434+ _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI void operator ()() {
435+ __vec_.__annotate_delete ();
436+ std::__debug_db_erase_c (std::addressof (__vec_));
437+
438+ if (__vec_.__begin_ != nullptr ) {
439+ __vec_.__clear ();
440+ __alloc_traits::deallocate (__vec_.__alloc (), __vec_.__begin_ , __vec_.capacity ());
441+ }
438442 }
439- }
443+
444+ private:
445+ vector& __vec_;
446+ };
447+
448+ public:
449+ _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI ~vector () { __destroy_vector (*this )(); }
440450
441451 _LIBCPP_CONSTEXPR_AFTER_CXX17 vector (const vector& __x);
442452 _LIBCPP_CONSTEXPR_AFTER_CXX17 vector (const vector& __x, const __type_identity_t <allocator_type>& __a);
@@ -1075,12 +1085,14 @@ template <class _Tp, class _Allocator>
10751085_LIBCPP_CONSTEXPR_AFTER_CXX17
10761086vector<_Tp, _Allocator>::vector(size_type __n)
10771087{
1078- _VSTD::__debug_db_insert_c (this );
1088+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1089+ std::__debug_db_insert_c (this );
10791090 if (__n > 0 )
10801091 {
10811092 __vallocate (__n);
10821093 __construct_at_end (__n);
10831094 }
1095+ __guard.__complete ();
10841096}
10851097
10861098#if _LIBCPP_STD_VER > 11
@@ -1089,25 +1101,29 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17
10891101vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
10901102 : __end_cap_(nullptr , __a)
10911103{
1092- _VSTD::__debug_db_insert_c (this );
1104+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1105+ std::__debug_db_insert_c (this );
10931106 if (__n > 0 )
10941107 {
10951108 __vallocate (__n);
10961109 __construct_at_end (__n);
10971110 }
1111+ __guard.__complete ();
10981112}
10991113#endif
11001114
11011115template <class _Tp , class _Allocator >
11021116_LIBCPP_CONSTEXPR_AFTER_CXX17
11031117vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
11041118{
1105- _VSTD::__debug_db_insert_c (this );
1119+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1120+ std::__debug_db_insert_c (this );
11061121 if (__n > 0 )
11071122 {
11081123 __vallocate (__n);
11091124 __construct_at_end (__n, __x);
11101125 }
1126+ __guard.__complete ();
11111127}
11121128
11131129template <class _Tp , class _Allocator >
@@ -1120,9 +1136,11 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first,
11201136 typename iterator_traits<_InputIterator>::reference>::value,
11211137 _InputIterator>::type __last)
11221138{
1123- _VSTD::__debug_db_insert_c (this );
1139+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1140+ std::__debug_db_insert_c (this );
11241141 for (; __first != __last; ++__first)
11251142 emplace_back (*__first);
1143+ __guard.__complete ();
11261144}
11271145
11281146template <class _Tp , class _Allocator >
@@ -1135,9 +1153,11 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, c
11351153 typename iterator_traits<_InputIterator>::reference>::value>::type*)
11361154 : __end_cap_(nullptr , __a)
11371155{
1138- _VSTD::__debug_db_insert_c (this );
1156+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1157+ std::__debug_db_insert_c (this );
11391158 for (; __first != __last; ++__first)
11401159 emplace_back (*__first);
1160+ __guard.__complete ();
11411161}
11421162
11431163template <class _Tp , class _Allocator >
@@ -1150,13 +1170,15 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first,
11501170 typename iterator_traits<_ForwardIterator>::reference>::value,
11511171 _ForwardIterator>::type __last)
11521172{
1153- _VSTD::__debug_db_insert_c (this );
1154- size_type __n = static_cast <size_type>(_VSTD::distance (__first, __last));
1173+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1174+ std::__debug_db_insert_c (this );
1175+ size_type __n = static_cast <size_type>(std::distance (__first, __last));
11551176 if (__n > 0 )
11561177 {
11571178 __vallocate (__n);
11581179 __construct_at_end (__first, __last, __n);
11591180 }
1181+ __guard.__complete ();
11601182}
11611183
11621184template <class _Tp , class _Allocator >
@@ -1169,41 +1191,47 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las
11691191 typename iterator_traits<_ForwardIterator>::reference>::value>::type*)
11701192 : __end_cap_(nullptr , __a)
11711193{
1172- _VSTD::__debug_db_insert_c (this );
1173- size_type __n = static_cast <size_type>(_VSTD::distance (__first, __last));
1194+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1195+ std::__debug_db_insert_c (this );
1196+ size_type __n = static_cast <size_type>(std::distance (__first, __last));
11741197 if (__n > 0 )
11751198 {
11761199 __vallocate (__n);
11771200 __construct_at_end (__first, __last, __n);
11781201 }
1202+ __guard.__complete ();
11791203}
11801204
11811205template <class _Tp , class _Allocator >
11821206_LIBCPP_CONSTEXPR_AFTER_CXX17
11831207vector<_Tp, _Allocator>::vector(const vector& __x)
11841208 : __end_cap_(nullptr , __alloc_traits::select_on_container_copy_construction(__x.__alloc()))
11851209{
1186- _VSTD::__debug_db_insert_c (this );
1210+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1211+ std::__debug_db_insert_c (this );
11871212 size_type __n = __x.size ();
11881213 if (__n > 0 )
11891214 {
11901215 __vallocate (__n);
11911216 __construct_at_end (__x.__begin_ , __x.__end_ , __n);
11921217 }
1218+ __guard.__complete ();
11931219}
11941220
11951221template <class _Tp , class _Allocator >
11961222_LIBCPP_CONSTEXPR_AFTER_CXX17
11971223vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t <allocator_type>& __a)
11981224 : __end_cap_(nullptr , __a)
11991225{
1200- _VSTD::__debug_db_insert_c (this );
1226+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1227+ std::__debug_db_insert_c (this );
12011228 size_type __n = __x.size ();
12021229 if (__n > 0 )
12031230 {
12041231 __vallocate (__n);
12051232 __construct_at_end (__x.__begin_ , __x.__end_ , __n);
12061233 }
1234+ __guard.__complete ();
12071235}
12081236
12091237template <class _Tp , class _Allocator >
@@ -1243,7 +1271,9 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_
12431271 else
12441272 {
12451273 typedef move_iterator<iterator> _Ip;
1274+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
12461275 assign (_Ip (__x.begin ()), _Ip (__x.end ()));
1276+ __guard.__complete ();
12471277 }
12481278}
12491279
@@ -1254,12 +1284,14 @@ _LIBCPP_CONSTEXPR_AFTER_CXX17
12541284inline _LIBCPP_INLINE_VISIBILITY
12551285vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
12561286{
1257- _VSTD::__debug_db_insert_c (this );
1287+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1288+ std::__debug_db_insert_c (this );
12581289 if (__il.size () > 0 )
12591290 {
12601291 __vallocate (__il.size ());
12611292 __construct_at_end (__il.begin (), __il.end (), __il.size ());
12621293 }
1294+ __guard.__complete ();
12631295}
12641296
12651297template <class _Tp , class _Allocator >
@@ -1268,12 +1300,14 @@ inline _LIBCPP_INLINE_VISIBILITY
12681300vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
12691301 : __end_cap_(nullptr , __a)
12701302{
1271- _VSTD::__debug_db_insert_c (this );
1303+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1304+ std::__debug_db_insert_c (this );
12721305 if (__il.size () > 0 )
12731306 {
12741307 __vallocate (__il.size ());
12751308 __construct_at_end (__il.begin (), __il.end (), __il.size ());
12761309 }
1310+ __guard.__complete ();
12771311}
12781312
12791313#endif // _LIBCPP_CXX03_LANG
@@ -2111,8 +2145,26 @@ public:
21112145#else
21122146 _NOEXCEPT;
21132147#endif
2114- _LIBCPP_CONSTEXPR_AFTER_CXX17 ~vector ();
2115- _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit vector (size_type __n);
2148+
2149+ private:
2150+ class __destroy_vector {
2151+ public:
2152+ _LIBCPP_CONSTEXPR __destroy_vector (vector& __vec) : __vec_(__vec) {}
2153+
2154+ _LIBCPP_CONSTEXPR_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI void operator ()() {
2155+ if (__vec_.__begin_ != nullptr )
2156+ __storage_traits::deallocate (__vec_.__alloc (), __vec_.__begin_ , __vec_.__cap ());
2157+ std::__debug_db_invalidate_all (this );
2158+ }
2159+
2160+ private:
2161+ vector& __vec_;
2162+ };
2163+
2164+ public:
2165+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 ~vector () { __destroy_vector (*this )(); }
2166+
2167+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit vector (size_type __n);
21162168#if _LIBCPP_STD_VER > 11
21172169 _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit vector (size_type __n, const allocator_type& __a);
21182170#endif
@@ -2647,12 +2699,14 @@ vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __la
26472699 __size_ (0 ),
26482700 __cap_alloc_ (0 , __default_init_tag ())
26492701{
2650- size_type __n = static_cast <size_type>(_VSTD::distance (__first, __last));
2702+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
2703+ size_type __n = static_cast <size_type>(std::distance (__first, __last));
26512704 if (__n > 0 )
26522705 {
26532706 __vallocate (__n);
26542707 __construct_at_end (__first, __last);
26552708 }
2709+ __guard.__complete ();
26562710}
26572711
26582712template <class _Allocator >
@@ -2664,12 +2718,14 @@ vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __la
26642718 __size_ (0 ),
26652719 __cap_alloc_ (0 , static_cast <__storage_allocator>(__a))
26662720{
2667- size_type __n = static_cast <size_type>(_VSTD::distance (__first, __last));
2721+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
2722+ size_type __n = static_cast <size_type>(std::distance (__first, __last));
26682723 if (__n > 0 )
26692724 {
26702725 __vallocate (__n);
26712726 __construct_at_end (__first, __last);
26722727 }
2728+ __guard.__complete ();
26732729}
26742730
26752731#ifndef _LIBCPP_CXX03_LANG
@@ -2706,15 +2762,6 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const alloca
27062762
27072763#endif // _LIBCPP_CXX03_LANG
27082764
2709- template <class _Allocator >
2710- _LIBCPP_CONSTEXPR_AFTER_CXX17
2711- vector<bool , _Allocator>::~vector ()
2712- {
2713- if (__begin_ != nullptr )
2714- __storage_traits::deallocate (__alloc (), __begin_, __cap ());
2715- std::__debug_db_invalidate_all (this );
2716- }
2717-
27182765template <class _Allocator >
27192766_LIBCPP_CONSTEXPR_AFTER_CXX17
27202767vector<bool , _Allocator>::vector (const vector& __v)
0 commit comments