@@ -1213,104 +1213,6 @@ private:
1213
1213
__node_pointer __cache_root_;
1214
1214
__node_pointer __cache_elem_;
1215
1215
};
1216
-
1217
- class __tree_deleter {
1218
- __node_allocator& __alloc_;
1219
-
1220
- public:
1221
- using pointer = __node_pointer;
1222
-
1223
- _LIBCPP_HIDE_FROM_ABI __tree_deleter (__node_allocator& __alloc) : __alloc_(__alloc) {}
1224
-
1225
- #ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
1226
- _LIBCPP_HIDE_FROM_ABI
1227
- #endif
1228
- void
1229
- operator ()(__node_pointer __ptr) {
1230
- if (!__ptr)
1231
- return ;
1232
-
1233
- (*this )(static_cast <__node_pointer>(__ptr->__left_ ));
1234
-
1235
- auto __right = __ptr->__right_ ;
1236
-
1237
- __node_traits::destroy (__alloc_, std::addressof (__ptr->__value_ ));
1238
- __node_traits::deallocate (__alloc_, __ptr, 1 );
1239
-
1240
- (*this )(static_cast <__node_pointer>(__right));
1241
- }
1242
- };
1243
-
1244
- // This copy construction will always produce a correct red-black-tree assuming the incoming tree is correct, since we
1245
- // copy the exact structure 1:1. Since this is for copy construction _only_ we know that we get a correct tree. If we
1246
- // didn't get a correct tree, the invariants of __tree are broken and we have a much bigger problem than an improperly
1247
- // balanced tree.
1248
- #ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
1249
- _LIBCPP_HIDE_FROM_ABI
1250
- #endif
1251
- __node_pointer
1252
- __copy_construct_tree (__node_pointer __src) {
1253
- if (!__src)
1254
- return nullptr ;
1255
-
1256
- __node_holder __new_node = __construct_node (__src->__value_ );
1257
-
1258
- unique_ptr<__node, __tree_deleter> __left (
1259
- __copy_construct_tree (static_cast <__node_pointer>(__src->__left_ )), __node_alloc_);
1260
- __node_pointer __right = __copy_construct_tree (static_cast <__node_pointer>(__src->__right_ ));
1261
-
1262
- __node_pointer __new_node_ptr = __new_node.release ();
1263
-
1264
- __new_node_ptr->__is_black_ = __src->__is_black_ ;
1265
- __new_node_ptr->__left_ = static_cast <__node_base_pointer>(__left.release ());
1266
- __new_node_ptr->__right_ = static_cast <__node_base_pointer>(__right);
1267
- if (__new_node_ptr->__left_ )
1268
- __new_node_ptr->__left_ ->__parent_ = static_cast <__end_node_pointer>(__new_node_ptr);
1269
- if (__new_node_ptr->__right_ )
1270
- __new_node_ptr->__right_ ->__parent_ = static_cast <__end_node_pointer>(__new_node_ptr);
1271
- return __new_node_ptr;
1272
- }
1273
-
1274
- // This copy assignment will always produce a correct red-black-tree assuming the incoming tree is correct, since our
1275
- // own tree is a red-black-tree and the incoming tree is a red-black-tree. The invariants of a red-black-tree are
1276
- // temporarily not met until all of the incoming red-black tree is copied.
1277
- #ifdef _LIBCPP_COMPILER_CLANG_BASED // FIXME: GCC complains about not being able to always_inline a recursive function
1278
- _LIBCPP_HIDE_FROM_ABI
1279
- #endif
1280
- __node_pointer
1281
- __copy_assign_tree (__node_pointer __dest, __node_pointer __src) {
1282
- if (!__src) {
1283
- destroy (__dest);
1284
- return nullptr ;
1285
- }
1286
-
1287
- __assign_value (__dest->__value_ , __src->__value_ );
1288
- __dest->__is_black_ = __src->__is_black_ ;
1289
-
1290
- // If we already have a left node in the destination tree, reuse it and copy-assign recursively
1291
- if (__dest->__left_ ) {
1292
- __dest->__left_ = static_cast <__node_base_pointer>(__copy_assign_tree (
1293
- static_cast <__node_pointer>(__dest->__left_ ), static_cast <__node_pointer>(__src->__left_ )));
1294
-
1295
- // Otherwise, we must create new nodes; copy-construct from here on
1296
- } else if (__src->__left_ ) {
1297
- auto __new_left = __copy_construct_tree (static_cast <__node_pointer>(__src->__left_ ));
1298
- __dest->__left_ = static_cast <__node_base_pointer>(__new_left);
1299
- __new_left->__parent_ = static_cast <__end_node_pointer>(__dest);
1300
- }
1301
-
1302
- // Identical to the left case above, just for the right nodes
1303
- if (__dest->__right_ ) {
1304
- __dest->__right_ = static_cast <__node_base_pointer>(__copy_assign_tree (
1305
- static_cast <__node_pointer>(__dest->__right_ ), static_cast <__node_pointer>(__src->__right_ )));
1306
- } else if (__src->__right_ ) {
1307
- auto __new_right = __copy_construct_tree (static_cast <__node_pointer>(__src->__right_ ));
1308
- __dest->__right_ = static_cast <__node_base_pointer>(__new_right);
1309
- __new_right->__parent_ = static_cast <__end_node_pointer>(__dest);
1310
- }
1311
-
1312
- return __dest;
1313
- }
1314
1216
};
1315
1217
1316
1218
template <class _Tp , class _Compare , class _Allocator >
@@ -1375,22 +1277,11 @@ __tree<_Tp, _Compare, _Allocator>::_DetachedTreeCache::__detach_next(__node_poin
1375
1277
1376
1278
template <class _Tp , class _Compare , class _Allocator >
1377
1279
__tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator =(const __tree& __t ) {
1378
- if (this == std::addressof (__t ))
1379
- return *this ;
1380
-
1381
- value_comp () = __t .value_comp ();
1382
- __copy_assign_alloc (__t );
1383
-
1384
- if (__size_ != 0 ) {
1385
- *__root_ptr () = static_cast <__node_base_pointer>(__copy_assign_tree (__root (), __t .__root ()));
1386
- } else {
1387
- *__root_ptr () = static_cast <__node_base_pointer>(__copy_construct_tree (__t .__root ()));
1388
- if (__root ())
1389
- __root ()->__parent_ = __end_node ();
1280
+ if (this != std::addressof (__t )) {
1281
+ value_comp () = __t .value_comp ();
1282
+ __copy_assign_alloc (__t );
1283
+ __assign_multi (__t .begin (), __t .end ());
1390
1284
}
1391
- __begin_node_ = static_cast <__end_node_pointer>(std::__tree_min (static_cast <__node_base_pointer>(__end_node ())));
1392
- __size_ = __t .size ();
1393
-
1394
1285
return *this ;
1395
1286
}
1396
1287
@@ -1436,17 +1327,11 @@ void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _
1436
1327
1437
1328
template <class _Tp , class _Compare , class _Allocator >
1438
1329
__tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t )
1439
- : __begin_node_(__end_node() ),
1330
+ : __begin_node_(),
1440
1331
__node_alloc_ (__node_traits::select_on_container_copy_construction(__t .__node_alloc())),
1441
1332
__size_(0 ),
1442
1333
__value_comp_(__t .value_comp()) {
1443
- if (__t .size () == 0 )
1444
- return ;
1445
-
1446
- *__root_ptr () = static_cast <__node_base_pointer>(__copy_construct_tree (__t .__root ()));
1447
- __root ()->__parent_ = __end_node ();
1448
- __begin_node_ = static_cast <__end_node_pointer>(std::__tree_min (static_cast <__node_base_pointer>(__end_node ())));
1449
- __size_ = __t .size ();
1334
+ __begin_node_ = __end_node ();
1450
1335
}
1451
1336
1452
1337
template <class _Tp , class _Compare , class _Allocator >
@@ -1545,7 +1430,13 @@ __tree<_Tp, _Compare, _Allocator>::~__tree() {
1545
1430
1546
1431
template <class _Tp , class _Compare , class _Allocator >
1547
1432
void __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT {
1548
- (__tree_deleter (__node_alloc_))(__nd);
1433
+ if (__nd != nullptr ) {
1434
+ destroy (static_cast <__node_pointer>(__nd->__left_ ));
1435
+ destroy (static_cast <__node_pointer>(__nd->__right_ ));
1436
+ __node_allocator& __na = __node_alloc ();
1437
+ __node_traits::destroy (__na, std::addressof (__nd->__value_ ));
1438
+ __node_traits::deallocate (__na, __nd, 1 );
1439
+ }
1549
1440
}
1550
1441
1551
1442
template <class _Tp , class _Compare , class _Allocator >
0 commit comments