@@ -302,6 +302,7 @@ erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
302
302
#include < __utility/forward.h>
303
303
#include < __utility/move.h>
304
304
#include < __utility/swap.h>
305
+ #include < __utility/transaction.h>
305
306
#include < climits>
306
307
#include < cstdlib>
307
308
#include < cstring>
@@ -423,18 +424,27 @@ public:
423
424
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
424
425
vector (_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a);
425
426
426
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
427
- ~vector ()
428
- {
429
- __annotate_delete ();
430
- std::__debug_db_erase_c (this );
427
+ private:
428
+ class __destroy_vector {
429
+ public:
430
+ _LIBCPP_CONSTEXPR __destroy_vector (vector& __vec) : __vec_(__vec) {}
431
431
432
- if (this ->__begin_ != nullptr )
433
- {
434
- __clear ();
435
- __alloc_traits::deallocate (__alloc (), this ->__begin_ , capacity ());
432
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator ()() {
433
+ __vec_.__annotate_delete ();
434
+ std::__debug_db_erase_c (std::addressof (__vec_));
435
+
436
+ if (__vec_.__begin_ != nullptr ) {
437
+ __vec_.__clear ();
438
+ __alloc_traits::deallocate (__vec_.__alloc (), __vec_.__begin_ , __vec_.capacity ());
439
+ }
436
440
}
437
- }
441
+
442
+ private:
443
+ vector& __vec_;
444
+ };
445
+
446
+ public:
447
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~vector () { __destroy_vector (*this )(); }
438
448
439
449
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector (const vector& __x);
440
450
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector (const vector& __x, const __type_identity_t <allocator_type>& __a);
@@ -1054,12 +1064,14 @@ template <class _Tp, class _Allocator>
1054
1064
_LIBCPP_CONSTEXPR_SINCE_CXX20
1055
1065
vector<_Tp, _Allocator>::vector(size_type __n)
1056
1066
{
1067
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1057
1068
std::__debug_db_insert_c (this );
1058
1069
if (__n > 0 )
1059
1070
{
1060
1071
__vallocate (__n);
1061
1072
__construct_at_end (__n);
1062
1073
}
1074
+ __guard.__complete ();
1063
1075
}
1064
1076
1065
1077
#if _LIBCPP_STD_VER > 11
@@ -1068,25 +1080,29 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
1068
1080
vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a)
1069
1081
: __end_cap_(nullptr , __a)
1070
1082
{
1083
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1071
1084
std::__debug_db_insert_c (this );
1072
1085
if (__n > 0 )
1073
1086
{
1074
1087
__vallocate (__n);
1075
1088
__construct_at_end (__n);
1076
1089
}
1090
+ __guard.__complete ();
1077
1091
}
1078
1092
#endif
1079
1093
1080
1094
template <class _Tp , class _Allocator >
1081
1095
_LIBCPP_CONSTEXPR_SINCE_CXX20
1082
1096
vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
1083
1097
{
1098
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1084
1099
std::__debug_db_insert_c (this );
1085
1100
if (__n > 0 )
1086
1101
{
1087
1102
__vallocate (__n);
1088
1103
__construct_at_end (__n, __x);
1089
1104
}
1105
+ __guard.__complete ();
1090
1106
}
1091
1107
1092
1108
template <class _Tp , class _Allocator >
@@ -1096,9 +1112,11 @@ template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<
1096
1112
_LIBCPP_CONSTEXPR_SINCE_CXX20
1097
1113
vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last)
1098
1114
{
1115
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1099
1116
std::__debug_db_insert_c (this );
1100
1117
for (; __first != __last; ++__first)
1101
1118
emplace_back (*__first);
1119
+ __guard.__complete ();
1102
1120
}
1103
1121
1104
1122
template <class _Tp , class _Allocator >
@@ -1109,9 +1127,11 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
1109
1127
vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a)
1110
1128
: __end_cap_(nullptr , __a)
1111
1129
{
1130
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1112
1131
std::__debug_db_insert_c (this );
1113
1132
for (; __first != __last; ++__first)
1114
1133
emplace_back (*__first);
1134
+ __guard.__complete ();
1115
1135
}
1116
1136
1117
1137
template <class _Tp , class _Allocator >
@@ -1121,13 +1141,15 @@ template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_For
1121
1141
_LIBCPP_CONSTEXPR_SINCE_CXX20
1122
1142
vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last)
1123
1143
{
1144
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1124
1145
std::__debug_db_insert_c (this );
1125
1146
size_type __n = static_cast <size_type>(std::distance (__first, __last));
1126
1147
if (__n > 0 )
1127
1148
{
1128
1149
__vallocate (__n);
1129
1150
__construct_at_end (__first, __last, __n);
1130
1151
}
1152
+ __guard.__complete ();
1131
1153
}
1132
1154
1133
1155
template <class _Tp , class _Allocator >
@@ -1138,41 +1160,47 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
1138
1160
vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a)
1139
1161
: __end_cap_(nullptr , __a)
1140
1162
{
1163
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1141
1164
std::__debug_db_insert_c (this );
1142
1165
size_type __n = static_cast <size_type>(std::distance (__first, __last));
1143
1166
if (__n > 0 )
1144
1167
{
1145
1168
__vallocate (__n);
1146
1169
__construct_at_end (__first, __last, __n);
1147
1170
}
1171
+ __guard.__complete ();
1148
1172
}
1149
1173
1150
1174
template <class _Tp , class _Allocator >
1151
1175
_LIBCPP_CONSTEXPR_SINCE_CXX20
1152
1176
vector<_Tp, _Allocator>::vector(const vector& __x)
1153
1177
: __end_cap_(nullptr , __alloc_traits::select_on_container_copy_construction(__x.__alloc()))
1154
1178
{
1179
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1155
1180
std::__debug_db_insert_c (this );
1156
1181
size_type __n = __x.size ();
1157
1182
if (__n > 0 )
1158
1183
{
1159
1184
__vallocate (__n);
1160
1185
__construct_at_end (__x.__begin_ , __x.__end_ , __n);
1161
1186
}
1187
+ __guard.__complete ();
1162
1188
}
1163
1189
1164
1190
template <class _Tp , class _Allocator >
1165
1191
_LIBCPP_CONSTEXPR_SINCE_CXX20
1166
1192
vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t <allocator_type>& __a)
1167
1193
: __end_cap_(nullptr , __a)
1168
1194
{
1195
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1169
1196
std::__debug_db_insert_c (this );
1170
1197
size_type __n = __x.size ();
1171
1198
if (__n > 0 )
1172
1199
{
1173
1200
__vallocate (__n);
1174
1201
__construct_at_end (__x.__begin_ , __x.__end_ , __n);
1175
1202
}
1203
+ __guard.__complete ();
1176
1204
}
1177
1205
1178
1206
template <class _Tp , class _Allocator >
@@ -1212,7 +1240,9 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_
1212
1240
else
1213
1241
{
1214
1242
typedef move_iterator<iterator> _Ip;
1243
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1215
1244
assign (_Ip (__x.begin ()), _Ip (__x.end ()));
1245
+ __guard.__complete ();
1216
1246
}
1217
1247
}
1218
1248
@@ -1223,12 +1253,14 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20
1223
1253
inline _LIBCPP_HIDE_FROM_ABI
1224
1254
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il)
1225
1255
{
1256
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1226
1257
std::__debug_db_insert_c (this );
1227
1258
if (__il.size () > 0 )
1228
1259
{
1229
1260
__vallocate (__il.size ());
1230
1261
__construct_at_end (__il.begin (), __il.end (), __il.size ());
1231
1262
}
1263
+ __guard.__complete ();
1232
1264
}
1233
1265
1234
1266
template <class _Tp , class _Allocator >
@@ -1237,12 +1269,14 @@ inline _LIBCPP_HIDE_FROM_ABI
1237
1269
vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
1238
1270
: __end_cap_(nullptr , __a)
1239
1271
{
1272
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
1240
1273
std::__debug_db_insert_c (this );
1241
1274
if (__il.size () > 0 )
1242
1275
{
1243
1276
__vallocate (__il.size ());
1244
1277
__construct_at_end (__il.begin (), __il.end (), __il.size ());
1245
1278
}
1279
+ __guard.__complete ();
1246
1280
}
1247
1281
1248
1282
#endif // _LIBCPP_CXX03_LANG
@@ -2060,7 +2094,25 @@ public:
2060
2094
#else
2061
2095
_NOEXCEPT;
2062
2096
#endif
2063
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector ();
2097
+
2098
+ private:
2099
+ class __destroy_vector {
2100
+ public:
2101
+ _LIBCPP_CONSTEXPR __destroy_vector (vector& __vec) : __vec_(__vec) {}
2102
+
2103
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator ()() {
2104
+ if (__vec_.__begin_ != nullptr )
2105
+ __storage_traits::deallocate (__vec_.__alloc (), __vec_.__begin_ , __vec_.__cap ());
2106
+ std::__debug_db_invalidate_all (this );
2107
+ }
2108
+
2109
+ private:
2110
+ vector& __vec_;
2111
+ };
2112
+
2113
+ public:
2114
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector () { __destroy_vector (*this )(); }
2115
+
2064
2116
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector (size_type __n);
2065
2117
#if _LIBCPP_STD_VER > 11
2066
2118
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector (size_type __n, const allocator_type& __a);
@@ -2596,12 +2648,14 @@ vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __la
2596
2648
__size_ (0 ),
2597
2649
__cap_alloc_ (0 , __default_init_tag ())
2598
2650
{
2651
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
2599
2652
size_type __n = static_cast <size_type>(std::distance (__first, __last));
2600
2653
if (__n > 0 )
2601
2654
{
2602
2655
__vallocate (__n);
2603
2656
__construct_at_end (__first, __last);
2604
2657
}
2658
+ __guard.__complete ();
2605
2659
}
2606
2660
2607
2661
template <class _Allocator >
@@ -2613,12 +2667,14 @@ vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __la
2613
2667
__size_ (0 ),
2614
2668
__cap_alloc_ (0 , static_cast <__storage_allocator>(__a))
2615
2669
{
2670
+ auto __guard = std::__make_transaction (__destroy_vector (*this ));
2616
2671
size_type __n = static_cast <size_type>(std::distance (__first, __last));
2617
2672
if (__n > 0 )
2618
2673
{
2619
2674
__vallocate (__n);
2620
2675
__construct_at_end (__first, __last);
2621
2676
}
2677
+ __guard.__complete ();
2622
2678
}
2623
2679
2624
2680
#ifndef _LIBCPP_CXX03_LANG
@@ -2655,15 +2711,6 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const alloca
2655
2711
2656
2712
#endif // _LIBCPP_CXX03_LANG
2657
2713
2658
- template <class _Allocator >
2659
- _LIBCPP_CONSTEXPR_SINCE_CXX20
2660
- vector<bool , _Allocator>::~vector ()
2661
- {
2662
- if (__begin_ != nullptr )
2663
- __storage_traits::deallocate (__alloc (), __begin_, __cap ());
2664
- std::__debug_db_invalidate_all (this );
2665
- }
2666
-
2667
2714
template <class _Allocator >
2668
2715
_LIBCPP_CONSTEXPR_SINCE_CXX20
2669
2716
vector<bool , _Allocator>::vector (const vector& __v)
0 commit comments