@@ -505,48 +505,24 @@ struct __is_tree_value_type<_One> : __is_tree_value_type_imp<__remove_cvref_t<_O
505
505
template <class _Tp >
506
506
struct __tree_key_value_types {
507
507
typedef _Tp key_type;
508
- typedef _Tp __node_value_type;
509
508
typedef _Tp __container_value_type;
510
509
static const bool __is_map = false ;
511
510
512
511
_LIBCPP_HIDE_FROM_ABI static key_type const & __get_key (_Tp const & __v) { return __v; }
513
- _LIBCPP_HIDE_FROM_ABI static __container_value_type const & __get_value (__node_value_type const & __v) { return __v; }
514
- _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr (__node_value_type& __n) { return std::addressof (__n); }
515
- _LIBCPP_HIDE_FROM_ABI static __container_value_type&& __move(__node_value_type& __v) { return std::move (__v); }
516
512
};
517
513
518
514
template <class _Key , class _Tp >
519
515
struct __tree_key_value_types <__value_type<_Key, _Tp> > {
520
516
typedef _Key key_type;
521
517
typedef _Tp mapped_type;
522
- typedef __value_type<_Key, _Tp> __node_value_type;
523
518
typedef pair<const _Key, _Tp> __container_value_type;
524
519
typedef __container_value_type __map_value_type;
525
520
static const bool __is_map = true ;
526
521
527
- _LIBCPP_HIDE_FROM_ABI static key_type const & __get_key (__node_value_type const & __t ) {
528
- return __t .__get_value ().first ;
529
- }
530
-
531
522
template <class _Up , __enable_if_t <__is_same_uncvref<_Up, __container_value_type>::value, int > = 0 >
532
523
_LIBCPP_HIDE_FROM_ABI static key_type const & __get_key (_Up& __t ) {
533
524
return __t .first ;
534
525
}
535
-
536
- _LIBCPP_HIDE_FROM_ABI static __container_value_type const & __get_value (__node_value_type const & __t ) {
537
- return __t .__get_value ();
538
- }
539
-
540
- template <class _Up , __enable_if_t <__is_same_uncvref<_Up, __container_value_type>::value, int > = 0 >
541
- _LIBCPP_HIDE_FROM_ABI static __container_value_type const & __get_value (_Up& __t ) {
542
- return __t ;
543
- }
544
-
545
- _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr (__node_value_type& __n) {
546
- return std::addressof (__n.__get_value ());
547
- }
548
-
549
- _LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move (__node_value_type& __v) { return __v.__move (); }
550
526
};
551
527
552
528
template <class _VoidPtr >
@@ -587,6 +563,19 @@ struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
587
563
typedef __rebind_pointer_t <_AllocPtr, const _Mv> __const_map_value_type_pointer;
588
564
};
589
565
566
+ template <class _Tp >
567
+ struct __get_node_value_type {
568
+ using type _LIBCPP_NODEBUG = _Tp;
569
+ };
570
+
571
+ template <class _Key , class _ValueT >
572
+ struct __get_node_value_type <__value_type<_Key, _ValueT> > {
573
+ using type _LIBCPP_NODEBUG = pair<const _Key, _ValueT>;
574
+ };
575
+
576
+ template <class _Tp >
577
+ using __get_node_value_type_t = typename __get_node_value_type<_Tp>::type;
578
+
590
579
template <class _NodePtr , class _NodeT = typename pointer_traits<_NodePtr>::element_type>
591
580
struct __tree_node_types ;
592
581
@@ -601,7 +590,7 @@ public:
601
590
typedef typename pointer_traits<_NodePtr>::element_type __node_type;
602
591
typedef _NodePtr __node_pointer;
603
592
604
- typedef _Tp __node_value_type;
593
+ using __node_value_type = __get_node_value_type_t <_Tp> ;
605
594
typedef __rebind_pointer_t <_VoidPtr, __node_value_type> __node_value_type_pointer;
606
595
typedef __rebind_pointer_t <_VoidPtr, const __node_value_type> __const_node_value_type_pointer;
607
596
typedef typename __base::__end_node_pointer __iter_pointer;
@@ -653,11 +642,11 @@ public:
653
642
template <class _Tp , class _VoidPtr >
654
643
class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
655
644
public:
656
- typedef _Tp __node_value_type;
645
+ using __node_value_type = __get_node_value_type_t <_Tp> ;
657
646
658
647
__node_value_type __value_;
659
648
660
- _LIBCPP_HIDE_FROM_ABI _Tp & __get_value () { return __value_; }
649
+ _LIBCPP_HIDE_FROM_ABI __node_value_type & __get_value () { return __value_; }
661
650
662
651
~__tree_node () = delete ;
663
652
__tree_node (__tree_node const &) = delete ;
@@ -688,7 +677,7 @@ public:
688
677
689
678
_LIBCPP_HIDE_FROM_ABI void operator ()(pointer __p) _NOEXCEPT {
690
679
if (__value_constructed)
691
- __alloc_traits::destroy (__na_, _NodeTypes::__get_ptr (__p->__value_ ));
680
+ __alloc_traits::destroy (__na_, std::addressof (__p->__value_ ));
692
681
if (__p)
693
682
__alloc_traits::deallocate (__na_, __p, 1 );
694
683
}
@@ -719,7 +708,7 @@ class _LIBCPP_TEMPLATE_VIS __tree_iterator {
719
708
720
709
public:
721
710
typedef bidirectional_iterator_tag iterator_category;
722
- typedef _Tp value_type;
711
+ using value_type = __get_node_value_type_t <_Tp> ;
723
712
typedef _DiffType difference_type;
724
713
typedef value_type& reference;
725
714
typedef typename _NodeTypes::__node_value_type_pointer pointer;
@@ -796,7 +785,7 @@ class _LIBCPP_TEMPLATE_VIS __tree_const_iterator {
796
785
797
786
public:
798
787
typedef bidirectional_iterator_tag iterator_category;
799
- typedef _Tp value_type;
788
+ using value_type = __get_node_value_type_t <_Tp> ;
800
789
typedef _DiffType difference_type;
801
790
typedef const value_type& reference;
802
791
typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
@@ -809,7 +798,7 @@ public:
809
798
}
810
799
811
800
private:
812
- typedef __tree_iterator<value_type , __node_pointer, difference_type> __non_const_iterator;
801
+ typedef __tree_iterator<_Tp , __node_pointer, difference_type> __non_const_iterator;
813
802
814
803
public:
815
804
_LIBCPP_HIDE_FROM_ABI __tree_const_iterator (__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
@@ -1276,6 +1265,32 @@ private:
1276
1265
}
1277
1266
_LIBCPP_HIDE_FROM_ABI void __move_assign_alloc (__tree&, false_type) _NOEXCEPT {}
1278
1267
1268
+ template <class _From , __enable_if_t <__is_pair_v<__remove_cvref_t <_From> >, int > = 0 >
1269
+ _LIBCPP_HIDE_FROM_ABI static void __assign_value (__get_node_value_type_t <value_type>& __lhs, _From&& __rhs) {
1270
+ using __punned_type = pair<typename _NodeTypes::key_type, typename _NodeTypes::mapped_type>;
1271
+
1272
+ reinterpret_cast <__punned_type&>(__lhs) = reinterpret_cast <__copy_cvref_t <_From, __punned_type>&&>(__rhs);
1273
+ }
1274
+
1275
+ template <class _To ,
1276
+ class _From ,
1277
+ class _ValueT = _Tp,
1278
+ __enable_if_t <__is_tree_value_type<_ValueT>::value && !__is_pair_v<__remove_cvref_t <_From> >, int > = 0 >
1279
+ _LIBCPP_HIDE_FROM_ABI static void __assign_value (_To& __lhs, _From&& __rhs) {
1280
+ static_assert (__is_pair_v<__remove_cvref_t <_From> >);
1281
+ using __punned_type = pair<typename _NodeTypes::key_type, typename _NodeTypes::mapped_type>;
1282
+
1283
+ reinterpret_cast <__punned_type&>(__lhs) = __rhs;
1284
+ }
1285
+
1286
+ template <class _To ,
1287
+ class _From ,
1288
+ class _ValueT = _Tp,
1289
+ __enable_if_t <!__is_tree_value_type<_ValueT>::value && !__is_pair_v<__remove_cvref_t <_From> >, int > = 0 >
1290
+ _LIBCPP_HIDE_FROM_ABI static void __assign_value (_To& __lhs, _From&& __rhs) {
1291
+ __lhs = std::forward<_From>(__rhs);
1292
+ }
1293
+
1279
1294
struct _DetachedTreeCache {
1280
1295
_LIBCPP_HIDE_FROM_ABI explicit _DetachedTreeCache (__tree* __t ) _NOEXCEPT
1281
1296
: __t_(__t ),
@@ -1416,13 +1431,13 @@ void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _
1416
1431
if (size () != 0 ) {
1417
1432
_DetachedTreeCache __cache (this );
1418
1433
for (; __cache.__get () && __first != __last; ++__first) {
1419
- __cache.__get ()->__value_ = *__first;
1434
+ __assign_value ( __cache.__get ()->__value_ , *__first) ;
1420
1435
__node_insert_multi (__cache.__get ());
1421
1436
__cache.__advance ();
1422
1437
}
1423
1438
}
1424
1439
for (; __first != __last; ++__first)
1425
- __insert_multi (_NodeTypes::__get_value ( *__first) );
1440
+ __insert_multi (*__first);
1426
1441
}
1427
1442
1428
1443
template <class _Tp , class _Compare , class _Allocator >
@@ -1501,13 +1516,19 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
1501
1516
if (size () != 0 ) {
1502
1517
_DetachedTreeCache __cache (this );
1503
1518
while (__cache.__get () != nullptr && __t .size () != 0 ) {
1504
- __cache.__get ()->__value_ = std::move (__t .remove (__t .begin ())->__value_ );
1519
+ __assign_value ( __cache.__get ()->__value_ , std::move (__t .remove (__t .begin ())->__value_ ) );
1505
1520
__node_insert_multi (__cache.__get ());
1506
1521
__cache.__advance ();
1507
1522
}
1508
1523
}
1509
- while (__t .size () != 0 )
1510
- __insert_multi (__e, _NodeTypes::__move (__t .remove (__t .begin ())->__value_ ));
1524
+ while (__t .size () != 0 ) {
1525
+ if constexpr (__is_tree_value_type<_Tp>::value) {
1526
+ using __punned_type = pair<typename _NodeTypes::key_type, typename _NodeTypes::mapped_type>;
1527
+ __insert_multi (__e, reinterpret_cast <__punned_type&&>(__t .remove (__t .begin ())->__value_ ));
1528
+ } else {
1529
+ __insert_multi (__e, std::move (__t .remove (__t .begin ())->__value_ ));
1530
+ }
1531
+ }
1511
1532
}
1512
1533
}
1513
1534
@@ -1533,7 +1554,7 @@ void __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT {
1533
1554
destroy (static_cast <__node_pointer>(__nd->__left_ ));
1534
1555
destroy (static_cast <__node_pointer>(__nd->__right_ ));
1535
1556
__node_allocator& __na = __node_alloc ();
1536
- __node_traits::destroy (__na, _NodeTypes::__get_ptr (__nd->__value_ ));
1557
+ __node_traits::destroy (__na, std::addressof (__nd->__value_ ));
1537
1558
__node_traits::deallocate (__na, __nd, 1 );
1538
1559
}
1539
1560
}
@@ -1803,10 +1824,9 @@ template <class _Tp, class _Compare, class _Allocator>
1803
1824
template <class ... _Args>
1804
1825
typename __tree<_Tp, _Compare, _Allocator>::__node_holder
1805
1826
__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
1806
- static_assert (!__is_tree_value_type<_Args...>::value, " Cannot construct from __value_type" );
1807
1827
__node_allocator& __na = __node_alloc ();
1808
1828
__node_holder __h (__node_traits::allocate (__na, 1 ), _Dp (__na));
1809
- __node_traits::construct (__na, _NodeTypes::__get_ptr (__h->__value_ ), std::forward<_Args>(__args)...);
1829
+ __node_traits::construct (__na, std::addressof (__h->__value_ ), std::forward<_Args>(__args)...);
1810
1830
__h.get_deleter ().__value_constructed = true ;
1811
1831
return __h;
1812
1832
}
@@ -1874,7 +1894,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_
1874
1894
__node_pointer __r = static_cast <__node_pointer>(__child);
1875
1895
bool __inserted = false ;
1876
1896
if (__child == nullptr ) {
1877
- __nd->__value_ = __v;
1897
+ __assign_value ( __nd->__value_ , __v) ;
1878
1898
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__nd));
1879
1899
__r = __nd;
1880
1900
__inserted = true ;
@@ -2036,7 +2056,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allo
2036
2056
__node_pointer __np = __p.__get_np ();
2037
2057
iterator __r = __remove_node_pointer (__np);
2038
2058
__node_allocator& __na = __node_alloc ();
2039
- __node_traits::destroy (__na, _NodeTypes::__get_ptr (const_cast <__node_value_type&>(*__p)));
2059
+ __node_traits::destroy (__na, std::addressof (const_cast <__node_value_type&>(*__p)));
2040
2060
__node_traits::deallocate (__na, __np, 1 );
2041
2061
return __r;
2042
2062
}
0 commit comments