1414#include < __assert>
1515#include < __config>
1616#include < __fwd/map.h>
17+ #include < __fwd/pair.h>
1718#include < __fwd/set.h>
1819#include < __iterator/distance.h>
1920#include < __iterator/iterator_traits.h>
2526#include < __memory/swap_allocator.h>
2627#include < __memory/unique_ptr.h>
2728#include < __type_traits/can_extract_key.h>
29+ #include < __type_traits/copy_cvref.h>
2830#include < __type_traits/enable_if.h>
2931#include < __type_traits/invoke.h>
3032#include < __type_traits/is_const.h>
@@ -505,48 +507,24 @@ struct __is_tree_value_type<_One> : __is_tree_value_type_imp<__remove_cvref_t<_O
505507template <class _Tp >
506508struct __tree_key_value_types {
507509 typedef _Tp key_type;
508- typedef _Tp __node_value_type;
509510 typedef _Tp __container_value_type;
510511 static const bool __is_map = false ;
511512
512513 _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); }
516514};
517515
518516template <class _Key , class _Tp >
519517struct __tree_key_value_types <__value_type<_Key, _Tp> > {
520518 typedef _Key key_type;
521519 typedef _Tp mapped_type;
522- typedef __value_type<_Key, _Tp> __node_value_type;
523520 typedef pair<const _Key, _Tp> __container_value_type;
524521 typedef __container_value_type __map_value_type;
525522 static const bool __is_map = true ;
526523
527- _LIBCPP_HIDE_FROM_ABI static key_type const & __get_key (__node_value_type const & __t ) {
528- return __t .__get_value ().first ;
529- }
530-
531524 template <class _Up , __enable_if_t <__is_same_uncvref<_Up, __container_value_type>::value, int > = 0 >
532525 _LIBCPP_HIDE_FROM_ABI static key_type const & __get_key (_Up& __t ) {
533526 return __t .first ;
534527 }
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 (); }
550528};
551529
552530template <class _VoidPtr >
@@ -587,6 +565,19 @@ struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
587565 typedef __rebind_pointer_t <_AllocPtr, const _Mv> __const_map_value_type_pointer;
588566};
589567
568+ template <class _Tp >
569+ struct __get_node_value_type {
570+ using type _LIBCPP_NODEBUG = _Tp;
571+ };
572+
573+ template <class _Key , class _ValueT >
574+ struct __get_node_value_type <__value_type<_Key, _ValueT> > {
575+ using type _LIBCPP_NODEBUG = pair<const _Key, _ValueT>;
576+ };
577+
578+ template <class _Tp >
579+ using __get_node_value_type_t _LIBCPP_NODEBUG = typename __get_node_value_type<_Tp>::type;
580+
590581template <class _NodePtr , class _NodeT = typename pointer_traits<_NodePtr>::element_type>
591582struct __tree_node_types ;
592583
@@ -601,7 +592,7 @@ public:
601592 typedef typename pointer_traits<_NodePtr>::element_type __node_type;
602593 typedef _NodePtr __node_pointer;
603594
604- typedef _Tp __node_value_type;
595+ using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t <_Tp> ;
605596 typedef __rebind_pointer_t <_VoidPtr, __node_value_type> __node_value_type_pointer;
606597 typedef __rebind_pointer_t <_VoidPtr, const __node_value_type> __const_node_value_type_pointer;
607598 typedef typename __base::__end_node_pointer __iter_pointer;
@@ -653,11 +644,11 @@ public:
653644template <class _Tp , class _VoidPtr >
654645class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
655646public:
656- typedef _Tp __node_value_type;
647+ using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t <_Tp> ;
657648
658649 __node_value_type __value_;
659650
660- _LIBCPP_HIDE_FROM_ABI _Tp & __get_value () { return __value_; }
651+ _LIBCPP_HIDE_FROM_ABI __node_value_type & __get_value () { return __value_; }
661652
662653 ~__tree_node () = delete ;
663654 __tree_node (__tree_node const &) = delete ;
@@ -688,7 +679,7 @@ public:
688679
689680 _LIBCPP_HIDE_FROM_ABI void operator ()(pointer __p) _NOEXCEPT {
690681 if (__value_constructed)
691- __alloc_traits::destroy (__na_, _NodeTypes::__get_ptr (__p->__value_ ));
682+ __alloc_traits::destroy (__na_, std::addressof (__p->__value_ ));
692683 if (__p)
693684 __alloc_traits::deallocate (__na_, __p, 1 );
694685 }
@@ -719,7 +710,7 @@ class __tree_iterator {
719710
720711public:
721712 typedef bidirectional_iterator_tag iterator_category;
722- typedef _Tp value_type;
713+ using value_type = __get_node_value_type_t <_Tp> ;
723714 typedef _DiffType difference_type;
724715 typedef value_type& reference;
725716 typedef typename _NodeTypes::__node_value_type_pointer pointer;
@@ -796,7 +787,7 @@ class __tree_const_iterator {
796787
797788public:
798789 typedef bidirectional_iterator_tag iterator_category;
799- typedef _Tp value_type;
790+ using value_type = __get_node_value_type_t <_Tp> ;
800791 typedef _DiffType difference_type;
801792 typedef const value_type& reference;
802793 typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
@@ -809,7 +800,7 @@ public:
809800 }
810801
811802private:
812- typedef __tree_iterator<value_type , __node_pointer, difference_type> __non_const_iterator;
803+ typedef __tree_iterator<_Tp , __node_pointer, difference_type> __non_const_iterator;
813804
814805public:
815806 _LIBCPP_HIDE_FROM_ABI __tree_const_iterator (__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
@@ -1135,6 +1126,17 @@ public:
11351126 return __emplace_hint_multi (__p, std::forward<_Vp>(__v));
11361127 }
11371128
1129+ template <class _ValueT = _Tp, __enable_if_t <__is_tree_value_type<_ValueT>::value, int > = 0 >
1130+ _LIBCPP_HIDE_FROM_ABI void __insert_from_orphaned_node (const_iterator __p, __get_node_value_type_t <_Tp>&& __value) {
1131+ using __key_type = _NodeTypes::key_type;
1132+ __emplace_hint_multi (__p, const_cast <__key_type&&>(__value.first ), std::move (__value.second ));
1133+ }
1134+
1135+ template <class _ValueT = _Tp, __enable_if_t <!__is_tree_value_type<_ValueT>::value, int > = 0 >
1136+ _LIBCPP_HIDE_FROM_ABI void __insert_from_orphaned_node (const_iterator __p, _Tp&& __value) {
1137+ __emplace_hint_multi (__p, std::move (__value));
1138+ }
1139+
11381140 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool >
11391141 __node_assign_unique (const __container_value_type& __v, __node_pointer __dest);
11401142
@@ -1276,6 +1278,19 @@ private:
12761278 }
12771279 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc (__tree&, false_type) _NOEXCEPT {}
12781280
1281+ template <class _From , __enable_if_t <__is_pair_v<__remove_cvref_t <_From> >, int > = 0 >
1282+ _LIBCPP_HIDE_FROM_ABI static void __assign_value (__get_node_value_type_t <value_type>& __lhs, _From&& __rhs) {
1283+ using __key_type = typename _NodeTypes::key_type;
1284+
1285+ const_cast <__key_type&>(__lhs.first ) = const_cast <__copy_cvref_t <_From, __key_type>&&>(__rhs.first );
1286+ __lhs.second = std::forward<_From>(__rhs).second ;
1287+ }
1288+
1289+ template <class _To , class _From , class _ValueT = _Tp, __enable_if_t <!__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+
12791294 struct _DetachedTreeCache {
12801295 _LIBCPP_HIDE_FROM_ABI explicit _DetachedTreeCache (__tree* __t ) _NOEXCEPT
12811296 : __t_(__t ),
@@ -1416,13 +1431,13 @@ void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _
14161431 if (size () != 0 ) {
14171432 _DetachedTreeCache __cache (this );
14181433 for (; __cache.__get () && __first != __last; ++__first) {
1419- __cache.__get ()->__value_ = *__first;
1434+ __assign_value ( __cache.__get ()->__value_ , *__first) ;
14201435 __node_insert_multi (__cache.__get ());
14211436 __cache.__advance ();
14221437 }
14231438 }
14241439 for (; __first != __last; ++__first)
1425- __insert_multi (_NodeTypes::__get_value ( *__first) );
1440+ __insert_multi (*__first);
14261441}
14271442
14281443template <class _Tp , class _Compare , class _Allocator >
@@ -1501,13 +1516,14 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
15011516 if (size () != 0 ) {
15021517 _DetachedTreeCache __cache (this );
15031518 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_ ) );
15051520 __node_insert_multi (__cache.__get ());
15061521 __cache.__advance ();
15071522 }
15081523 }
1509- while (__t .size () != 0 )
1510- __insert_multi (__e, _NodeTypes::__move (__t .remove (__t .begin ())->__value_ ));
1524+ while (__t .size () != 0 ) {
1525+ __insert_from_orphaned_node (__e, std::move (__t .remove (__t .begin ())->__value_ ));
1526+ }
15111527 }
15121528}
15131529
@@ -1533,7 +1549,7 @@ void __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT {
15331549 destroy (static_cast <__node_pointer>(__nd->__left_ ));
15341550 destroy (static_cast <__node_pointer>(__nd->__right_ ));
15351551 __node_allocator& __na = __node_alloc ();
1536- __node_traits::destroy (__na, _NodeTypes::__get_ptr (__nd->__value_ ));
1552+ __node_traits::destroy (__na, std::addressof (__nd->__value_ ));
15371553 __node_traits::deallocate (__na, __nd, 1 );
15381554 }
15391555}
@@ -1803,10 +1819,9 @@ template <class _Tp, class _Compare, class _Allocator>
18031819template <class ... _Args>
18041820typename __tree<_Tp, _Compare, _Allocator>::__node_holder
18051821__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
1806- static_assert (!__is_tree_value_type<_Args...>::value, " Cannot construct from __value_type" );
18071822 __node_allocator& __na = __node_alloc ();
18081823 __node_holder __h (__node_traits::allocate (__na, 1 ), _Dp (__na));
1809- __node_traits::construct (__na, _NodeTypes::__get_ptr (__h->__value_ ), std::forward<_Args>(__args)...);
1824+ __node_traits::construct (__na, std::addressof (__h->__value_ ), std::forward<_Args>(__args)...);
18101825 __h.get_deleter ().__value_constructed = true ;
18111826 return __h;
18121827}
@@ -1874,7 +1889,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_
18741889 __node_pointer __r = static_cast <__node_pointer>(__child);
18751890 bool __inserted = false ;
18761891 if (__child == nullptr ) {
1877- __nd->__value_ = __v;
1892+ __assign_value ( __nd->__value_ , __v) ;
18781893 __insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__nd));
18791894 __r = __nd;
18801895 __inserted = true ;
@@ -2036,7 +2051,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allo
20362051 __node_pointer __np = __p.__get_np ();
20372052 iterator __r = __remove_node_pointer (__np);
20382053 __node_allocator& __na = __node_alloc ();
2039- __node_traits::destroy (__na, _NodeTypes::__get_ptr (const_cast <__node_value_type&>(*__p)));
2054+ __node_traits::destroy (__na, std::addressof (const_cast <__node_value_type&>(*__p)));
20402055 __node_traits::deallocate (__na, __np, 1 );
20412056 return __r;
20422057}
0 commit comments