@@ -1117,7 +1117,12 @@ public:
1117
1117
_CONSTEXPR20_DYNALLOC _Container_base12& operator=(const _Container_base12&) = delete;
1118
1118
1119
1119
_CONSTEXPR20_DYNALLOC void _Orphan_all() noexcept;
1120
+ _CONSTEXPR20_DYNALLOC void _Orphan_all_unlocked() noexcept;
1121
+ void _Orphan_all_locked() noexcept;
1122
+
1120
1123
_CONSTEXPR20_DYNALLOC void _Swap_proxy_and_iterators(_Container_base12&) noexcept;
1124
+ _CONSTEXPR20_DYNALLOC void _Swap_proxy_and_iterators_unlocked(_Container_base12&) noexcept;
1125
+ void _Swap_proxy_and_iterators_locked(_Container_base12&) noexcept;
1121
1126
1122
1127
template <class _Alloc>
1123
1128
_CONSTEXPR20_DYNALLOC void _Alloc_proxy(_Alloc&& _Al) {
@@ -1140,19 +1145,20 @@ public:
1140
1145
};
1141
1146
1142
1147
struct _Iterator_base12 { // store links to container proxy, next iterator
1143
- _Iterator_base12() noexcept : _Myproxy(nullptr), _Mynextiter(nullptr) {} // construct orphaned iterator
1148
+ _CONSTEXPR20_DYNALLOC _Iterator_base12() noexcept
1149
+ : _Myproxy(nullptr), _Mynextiter(nullptr) {} // construct orphaned iterator
1144
1150
1145
- _Iterator_base12(const _Iterator_base12& _Right) noexcept : _Myproxy(nullptr), _Mynextiter(nullptr) {
1151
+ _CONSTEXPR20_DYNALLOC _Iterator_base12(const _Iterator_base12& _Right) noexcept
1152
+ : _Myproxy(nullptr), _Mynextiter(nullptr) {
1146
1153
*this = _Right;
1147
1154
}
1148
1155
1149
- _Iterator_base12& operator=(const _Iterator_base12& _Right) noexcept {
1156
+ _CONSTEXPR20_DYNALLOC _Iterator_base12& operator=(const _Iterator_base12& _Right) noexcept {
1150
1157
if (_Myproxy != _Right._Myproxy) {
1151
1158
if (_Right._Myproxy) {
1152
1159
_Adopt(_Right._Myproxy->_Mycont);
1153
1160
} else { // becoming invalid, disown current parent
1154
1161
#if _ITERATOR_DEBUG_LEVEL == 2
1155
- _Lockit _Lock(_LOCK_DEBUG);
1156
1162
_Orphan_me();
1157
1163
#else // _ITERATOR_DEBUG_LEVEL == 2
1158
1164
_Myproxy = nullptr;
@@ -1163,21 +1169,19 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
1163
1169
return *this;
1164
1170
}
1165
1171
1166
- ~_Iterator_base12() noexcept {
1172
+ _CONSTEXPR20_DYNALLOC ~_Iterator_base12() noexcept {
1167
1173
#if _ITERATOR_DEBUG_LEVEL == 2
1168
- _Lockit _Lock(_LOCK_DEBUG);
1169
1174
_Orphan_me();
1170
1175
#endif // _ITERATOR_DEBUG_LEVEL == 2
1171
1176
}
1172
1177
1173
- void _Adopt(const _Container_base12* _Parent) noexcept {
1178
+ _CONSTEXPR20_DYNALLOC void _Adopt(const _Container_base12* _Parent) noexcept {
1174
1179
if (_Parent) {
1175
1180
// have a parent, do adoption
1176
1181
_Container_proxy* _Parent_proxy = _Parent->_Myproxy;
1177
1182
1178
1183
#if _ITERATOR_DEBUG_LEVEL == 2
1179
1184
if (_Myproxy != _Parent_proxy) { // change parentage
1180
- _Lockit _Lock(_LOCK_DEBUG);
1181
1185
_Orphan_me();
1182
1186
_Mynextiter = _Parent_proxy->_Myfirstiter;
1183
1187
_Parent_proxy->_Myfirstiter = this;
@@ -1190,20 +1194,19 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
1190
1194
} else {
1191
1195
// no future parent, just disown current parent
1192
1196
#if _ITERATOR_DEBUG_LEVEL == 2
1193
- _Lockit _Lock(_LOCK_DEBUG);
1194
1197
_Orphan_me();
1195
1198
#else // _ITERATOR_DEBUG_LEVEL == 2
1196
1199
_Myproxy = nullptr;
1197
1200
#endif // _ITERATOR_DEBUG_LEVEL == 2
1198
1201
}
1199
1202
}
1200
1203
1201
- const _Container_base12* _Getcont() const noexcept {
1204
+ _CONSTEXPR20_DYNALLOC const _Container_base12* _Getcont() const noexcept {
1202
1205
return _Myproxy ? _Myproxy->_Mycont : nullptr;
1203
1206
}
1204
1207
1205
1208
#if _ITERATOR_DEBUG_LEVEL == 2
1206
- void _Orphan_me () noexcept {
1209
+ _CONSTEXPR20_DYNALLOC void _Orphan_me_unlocked () noexcept {
1207
1210
if (_Myproxy) { // adopted, remove self from list
1208
1211
_Iterator_base12** _Pnext = &_Myproxy->_Myfirstiter;
1209
1212
while (*_Pnext && *_Pnext != this) {
@@ -1215,6 +1218,22 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
1215
1218
_Myproxy = nullptr;
1216
1219
}
1217
1220
}
1221
+
1222
+ void _Orphan_me_locked() noexcept {
1223
+ _Lockit _Lock(_LOCK_DEBUG);
1224
+ _Orphan_me_unlocked();
1225
+ }
1226
+
1227
+ _CONSTEXPR20_DYNALLOC void _Orphan_me() noexcept {
1228
+ #ifdef __cpp_lib_is_constant_evaluated
1229
+ if (_STD is_constant_evaluated()) {
1230
+ _Orphan_me_unlocked();
1231
+ } else
1232
+ #endif // __cpp_lib_is_constant_evaluated
1233
+ {
1234
+ _Orphan_me_locked();
1235
+ }
1236
+ }
1218
1237
#endif // _ITERATOR_DEBUG_LEVEL == 2
1219
1238
1220
1239
static constexpr bool _Unwrap_when_unverified = _ITERATOR_DEBUG_LEVEL == 0;
@@ -1224,25 +1243,35 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
1224
1243
};
1225
1244
1226
1245
// MEMBER FUNCTIONS FOR _Container_base12
1227
- _CONSTEXPR20_DYNALLOC void _Container_base12::_Orphan_all() noexcept {
1228
- #if 0 //_ITERATOR_DEBUG_LEVEL == 2
1229
- if (_Myproxy) { // proxy allocated, drain it
1230
- _Lockit _Lock(_LOCK_DEBUG);
1231
-
1232
- for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
1233
- (*_Pnext)->_Myproxy = nullptr;
1234
- }
1235
-
1236
- _Myproxy->_Myfirstiter = nullptr;
1246
+ _CONSTEXPR20_DYNALLOC void _Container_base12::_Orphan_all_unlocked() noexcept {
1247
+ for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
1248
+ (*_Pnext)->_Myproxy = nullptr;
1237
1249
}
1238
- #endif // _ITERATOR_DEBUG_LEVEL == 2
1250
+
1251
+ _Myproxy->_Myfirstiter = nullptr;
1239
1252
}
1240
1253
1241
- _CONSTEXPR20_DYNALLOC void _Container_base12::_Swap_proxy_and_iterators(_Container_base12& _Right ) noexcept {
1242
- #if 0 // _ITERATOR_DEBUG_LEVEL == 2
1254
+ void _Container_base12::_Orphan_all_locked( ) noexcept {
1255
+ #if _ITERATOR_DEBUG_LEVEL == 2
1243
1256
_Lockit _Lock(_LOCK_DEBUG);
1244
1257
#endif // _ITERATOR_DEBUG_LEVEL == 2
1258
+ _Orphan_all_unlocked();
1259
+ }
1245
1260
1261
+ _CONSTEXPR20_DYNALLOC void _Container_base12::_Orphan_all() noexcept {
1262
+ if (_Myproxy) { // proxy allocated, drain it
1263
+ #ifdef __cpp_lib_is_constant_evaluated
1264
+ if (_STD is_constant_evaluated()) {
1265
+ _Orphan_all_unlocked();
1266
+ } else
1267
+ #endif // __cpp_lib_is_constant_evaluated
1268
+ {
1269
+ _Orphan_all_locked();
1270
+ }
1271
+ }
1272
+ }
1273
+
1274
+ _CONSTEXPR20_DYNALLOC void _Container_base12::_Swap_proxy_and_iterators_unlocked(_Container_base12& _Right) noexcept {
1246
1275
_Container_proxy* _Temp = _Myproxy;
1247
1276
_Myproxy = _Right._Myproxy;
1248
1277
_Right._Myproxy = _Temp;
@@ -1256,6 +1285,24 @@ _CONSTEXPR20_DYNALLOC void _Container_base12::_Swap_proxy_and_iterators(_Contain
1256
1285
}
1257
1286
}
1258
1287
1288
+ void _Container_base12::_Swap_proxy_and_iterators_locked(_Container_base12& _Right) noexcept {
1289
+ #if _ITERATOR_DEBUG_LEVEL == 2
1290
+ _Lockit _Lock(_LOCK_DEBUG);
1291
+ #endif // _ITERATOR_DEBUG_LEVEL == 2
1292
+ _Swap_proxy_and_iterators_unlocked(_Right);
1293
+ }
1294
+
1295
+ _CONSTEXPR20_DYNALLOC void _Container_base12::_Swap_proxy_and_iterators(_Container_base12& _Right) noexcept {
1296
+ #ifdef __cpp_lib_is_constant_evaluated
1297
+ if (_STD is_constant_evaluated()) {
1298
+ _Swap_proxy_and_iterators_unlocked(_Right);
1299
+ } else
1300
+ #endif // __cpp_lib_is_constant_evaluated
1301
+ {
1302
+ _Swap_proxy_and_iterators_locked(_Right);
1303
+ }
1304
+ }
1305
+
1259
1306
#if _ITERATOR_DEBUG_LEVEL == 0
1260
1307
using _Container_base = _Container_base0;
1261
1308
using _Iterator_base = _Iterator_base0;
@@ -1283,12 +1330,12 @@ struct _Basic_container_proxy_ptr12 {
1283
1330
// smart pointer components for a _Container_proxy * that don't depend on the allocator
1284
1331
_Container_proxy* _Ptr;
1285
1332
1286
- void _Release() noexcept { // disengage this _Basic_container_proxy_ptr12
1333
+ _CONSTEXPR20_DYNALLOC void _Release() noexcept { // disengage this _Basic_container_proxy_ptr12
1287
1334
_Ptr = nullptr;
1288
1335
}
1289
1336
1290
1337
protected:
1291
- _Basic_container_proxy_ptr12() = default;
1338
+ _CONSTEXPR20_DYNALLOC _Basic_container_proxy_ptr12() = default;
1292
1339
_Basic_container_proxy_ptr12(const _Basic_container_proxy_ptr12&) = delete;
1293
1340
_Basic_container_proxy_ptr12(_Basic_container_proxy_ptr12&&) = delete;
1294
1341
};
@@ -1298,26 +1345,27 @@ struct _Container_proxy_ptr12 : _Basic_container_proxy_ptr12 {
1298
1345
// smart pointer components for a _Container_proxy * for an allocator family
1299
1346
_Alloc& _Al;
1300
1347
1301
- _Container_proxy_ptr12(_Alloc& _Al_, _Leave_proxy_unbound) : _Al(_Al_) { // create a new unbound _Container_proxy
1348
+ _CONSTEXPR20_DYNALLOC _Container_proxy_ptr12(_Alloc& _Al_, _Leave_proxy_unbound)
1349
+ : _Al(_Al_) { // create a new unbound _Container_proxy
1302
1350
_Ptr = _Unfancy(_Al_.allocate(1));
1303
1351
_Construct_in_place(*_Ptr);
1304
1352
}
1305
1353
1306
- _Container_proxy_ptr12(_Alloc& _Al_, _Container_base12& _Mycont)
1354
+ _CONSTEXPR20_DYNALLOC _Container_proxy_ptr12(_Alloc& _Al_, _Container_base12& _Mycont)
1307
1355
: _Al(_Al_) { // create a new _Container_proxy pointing at _Mycont
1308
1356
_Ptr = _Unfancy(_Al_.allocate(1));
1309
1357
_Construct_in_place(*_Ptr, _STD addressof(_Mycont));
1310
1358
_Mycont._Myproxy = _Ptr;
1311
1359
}
1312
1360
1313
- void _Bind(_Alloc& _Old_alloc, _Container_base12* _Mycont) noexcept {
1361
+ _CONSTEXPR20_DYNALLOC void _Bind(_Alloc& _Old_alloc, _Container_base12* _Mycont) noexcept {
1314
1362
// Attach the proxy stored in *this to _Mycont, and destroy _Mycont's existing proxy
1315
1363
// with _Old_alloc. Requires that no iterators are alive referring to _Mycont.
1316
1364
_Ptr->_Mycont = _Mycont;
1317
1365
_Delete_plain_internal(_Old_alloc, _STD exchange(_Mycont->_Myproxy, _STD exchange(_Ptr, nullptr)));
1318
1366
}
1319
1367
1320
- ~_Container_proxy_ptr12() {
1368
+ _CONSTEXPR20_DYNALLOC ~_Container_proxy_ptr12() {
1321
1369
if (_Ptr) {
1322
1370
_Delete_plain_internal(_Al, _Ptr);
1323
1371
}
0 commit comments