Skip to content

Commit b75ed25

Browse files
committed
Fix _Container_base12
1 parent df5520f commit b75ed25

File tree

1 file changed

+78
-30
lines changed

1 file changed

+78
-30
lines changed

stl/inc/xmemory

+78-30
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,12 @@ public:
11171117
_CONSTEXPR20_DYNALLOC _Container_base12& operator=(const _Container_base12&) = delete;
11181118

11191119
_CONSTEXPR20_DYNALLOC void _Orphan_all() noexcept;
1120+
_CONSTEXPR20_DYNALLOC void _Orphan_all_unlocked() noexcept;
1121+
void _Orphan_all_locked() noexcept;
1122+
11201123
_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;
11211126

11221127
template <class _Alloc>
11231128
_CONSTEXPR20_DYNALLOC void _Alloc_proxy(_Alloc&& _Al) {
@@ -1140,19 +1145,20 @@ public:
11401145
};
11411146

11421147
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
11441150

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) {
11461153
*this = _Right;
11471154
}
11481155

1149-
_Iterator_base12& operator=(const _Iterator_base12& _Right) noexcept {
1156+
_CONSTEXPR20_DYNALLOC _Iterator_base12& operator=(const _Iterator_base12& _Right) noexcept {
11501157
if (_Myproxy != _Right._Myproxy) {
11511158
if (_Right._Myproxy) {
11521159
_Adopt(_Right._Myproxy->_Mycont);
11531160
} else { // becoming invalid, disown current parent
11541161
#if _ITERATOR_DEBUG_LEVEL == 2
1155-
_Lockit _Lock(_LOCK_DEBUG);
11561162
_Orphan_me();
11571163
#else // _ITERATOR_DEBUG_LEVEL == 2
11581164
_Myproxy = nullptr;
@@ -1163,21 +1169,19 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
11631169
return *this;
11641170
}
11651171

1166-
~_Iterator_base12() noexcept {
1172+
_CONSTEXPR20_DYNALLOC ~_Iterator_base12() noexcept {
11671173
#if _ITERATOR_DEBUG_LEVEL == 2
1168-
_Lockit _Lock(_LOCK_DEBUG);
11691174
_Orphan_me();
11701175
#endif // _ITERATOR_DEBUG_LEVEL == 2
11711176
}
11721177

1173-
void _Adopt(const _Container_base12* _Parent) noexcept {
1178+
_CONSTEXPR20_DYNALLOC void _Adopt(const _Container_base12* _Parent) noexcept {
11741179
if (_Parent) {
11751180
// have a parent, do adoption
11761181
_Container_proxy* _Parent_proxy = _Parent->_Myproxy;
11771182

11781183
#if _ITERATOR_DEBUG_LEVEL == 2
11791184
if (_Myproxy != _Parent_proxy) { // change parentage
1180-
_Lockit _Lock(_LOCK_DEBUG);
11811185
_Orphan_me();
11821186
_Mynextiter = _Parent_proxy->_Myfirstiter;
11831187
_Parent_proxy->_Myfirstiter = this;
@@ -1190,20 +1194,19 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
11901194
} else {
11911195
// no future parent, just disown current parent
11921196
#if _ITERATOR_DEBUG_LEVEL == 2
1193-
_Lockit _Lock(_LOCK_DEBUG);
11941197
_Orphan_me();
11951198
#else // _ITERATOR_DEBUG_LEVEL == 2
11961199
_Myproxy = nullptr;
11971200
#endif // _ITERATOR_DEBUG_LEVEL == 2
11981201
}
11991202
}
12001203

1201-
const _Container_base12* _Getcont() const noexcept {
1204+
_CONSTEXPR20_DYNALLOC const _Container_base12* _Getcont() const noexcept {
12021205
return _Myproxy ? _Myproxy->_Mycont : nullptr;
12031206
}
12041207

12051208
#if _ITERATOR_DEBUG_LEVEL == 2
1206-
void _Orphan_me() noexcept {
1209+
_CONSTEXPR20_DYNALLOC void _Orphan_me_unlocked() noexcept {
12071210
if (_Myproxy) { // adopted, remove self from list
12081211
_Iterator_base12** _Pnext = &_Myproxy->_Myfirstiter;
12091212
while (*_Pnext && *_Pnext != this) {
@@ -1215,6 +1218,22 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
12151218
_Myproxy = nullptr;
12161219
}
12171220
}
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+
}
12181237
#endif // _ITERATOR_DEBUG_LEVEL == 2
12191238

12201239
static constexpr bool _Unwrap_when_unverified = _ITERATOR_DEBUG_LEVEL == 0;
@@ -1224,25 +1243,35 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
12241243
};
12251244

12261245
// 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;
12371249
}
1238-
#endif // _ITERATOR_DEBUG_LEVEL == 2
1250+
1251+
_Myproxy->_Myfirstiter = nullptr;
12391252
}
12401253

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
12431256
_Lockit _Lock(_LOCK_DEBUG);
12441257
#endif // _ITERATOR_DEBUG_LEVEL == 2
1258+
_Orphan_all_unlocked();
1259+
}
12451260

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 {
12461275
_Container_proxy* _Temp = _Myproxy;
12471276
_Myproxy = _Right._Myproxy;
12481277
_Right._Myproxy = _Temp;
@@ -1256,6 +1285,24 @@ _CONSTEXPR20_DYNALLOC void _Container_base12::_Swap_proxy_and_iterators(_Contain
12561285
}
12571286
}
12581287

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+
12591306
#if _ITERATOR_DEBUG_LEVEL == 0
12601307
using _Container_base = _Container_base0;
12611308
using _Iterator_base = _Iterator_base0;
@@ -1283,12 +1330,12 @@ struct _Basic_container_proxy_ptr12 {
12831330
// smart pointer components for a _Container_proxy * that don't depend on the allocator
12841331
_Container_proxy* _Ptr;
12851332

1286-
void _Release() noexcept { // disengage this _Basic_container_proxy_ptr12
1333+
_CONSTEXPR20_DYNALLOC void _Release() noexcept { // disengage this _Basic_container_proxy_ptr12
12871334
_Ptr = nullptr;
12881335
}
12891336

12901337
protected:
1291-
_Basic_container_proxy_ptr12() = default;
1338+
_CONSTEXPR20_DYNALLOC _Basic_container_proxy_ptr12() = default;
12921339
_Basic_container_proxy_ptr12(const _Basic_container_proxy_ptr12&) = delete;
12931340
_Basic_container_proxy_ptr12(_Basic_container_proxy_ptr12&&) = delete;
12941341
};
@@ -1298,26 +1345,27 @@ struct _Container_proxy_ptr12 : _Basic_container_proxy_ptr12 {
12981345
// smart pointer components for a _Container_proxy * for an allocator family
12991346
_Alloc& _Al;
13001347

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
13021350
_Ptr = _Unfancy(_Al_.allocate(1));
13031351
_Construct_in_place(*_Ptr);
13041352
}
13051353

1306-
_Container_proxy_ptr12(_Alloc& _Al_, _Container_base12& _Mycont)
1354+
_CONSTEXPR20_DYNALLOC _Container_proxy_ptr12(_Alloc& _Al_, _Container_base12& _Mycont)
13071355
: _Al(_Al_) { // create a new _Container_proxy pointing at _Mycont
13081356
_Ptr = _Unfancy(_Al_.allocate(1));
13091357
_Construct_in_place(*_Ptr, _STD addressof(_Mycont));
13101358
_Mycont._Myproxy = _Ptr;
13111359
}
13121360

1313-
void _Bind(_Alloc& _Old_alloc, _Container_base12* _Mycont) noexcept {
1361+
_CONSTEXPR20_DYNALLOC void _Bind(_Alloc& _Old_alloc, _Container_base12* _Mycont) noexcept {
13141362
// Attach the proxy stored in *this to _Mycont, and destroy _Mycont's existing proxy
13151363
// with _Old_alloc. Requires that no iterators are alive referring to _Mycont.
13161364
_Ptr->_Mycont = _Mycont;
13171365
_Delete_plain_internal(_Old_alloc, _STD exchange(_Mycont->_Myproxy, _STD exchange(_Ptr, nullptr)));
13181366
}
13191367

1320-
~_Container_proxy_ptr12() {
1368+
_CONSTEXPR20_DYNALLOC ~_Container_proxy_ptr12() {
13211369
if (_Ptr) {
13221370
_Delete_plain_internal(_Al, _Ptr);
13231371
}

0 commit comments

Comments
 (0)