diff --git a/libcxx/include/__fwd/pair.h b/libcxx/include/__fwd/pair.h index ea81a81ef8e11..cf07eabab6903 100644 --- a/libcxx/include/__fwd/pair.h +++ b/libcxx/include/__fwd/pair.h @@ -22,6 +22,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD template struct pair; +template +inline const bool __is_pair_v = false; + +template +inline const bool __is_pair_v > = true; + template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(pair<_T1, _T2>&) _NOEXCEPT; diff --git a/libcxx/include/__memory/uses_allocator_construction.h b/libcxx/include/__memory/uses_allocator_construction.h index 955879ffc5845..49ddf99d9cc95 100644 --- a/libcxx/include/__memory/uses_allocator_construction.h +++ b/libcxx/include/__memory/uses_allocator_construction.h @@ -14,7 +14,6 @@ #include <__memory/uses_allocator.h> #include <__tuple/tuple_like_no_subrange.h> #include <__type_traits/enable_if.h> -#include <__type_traits/is_same.h> #include <__type_traits/remove_cv.h> #include <__utility/declval.h> #include <__utility/pair.h> @@ -31,14 +30,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -template -inline constexpr bool __is_std_pair = false; - -template -inline constexpr bool __is_std_pair> = true; - template -inline constexpr bool __is_cv_std_pair = __is_std_pair>; +inline constexpr bool __is_cv_std_pair = __is_pair_v>; template struct __uses_allocator_construction_args; diff --git a/libcxx/include/__node_handle b/libcxx/include/__node_handle index 08c4ffa5ff17b..5c559c657ef50 100644 --- a/libcxx/include/__node_handle +++ b/libcxx/include/__node_handle @@ -62,6 +62,7 @@ public: #include <__config> #include <__memory/allocator_traits.h> #include <__memory/pointer_traits.h> +#include <__type_traits/is_specialization.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -173,17 +174,40 @@ struct __set_node_handle_specifics { _LIBCPP_HIDE_FROM_ABI value_type& value() const { return static_cast<_Derived const*>(this)->__ptr_->__get_value(); } }; +template +struct __hash_value_type; + template struct __map_node_handle_specifics { - typedef typename _NodeType::__node_value_type::key_type key_type; - typedef typename _NodeType::__node_value_type::mapped_type mapped_type; + template + struct __get_type { + using key_type = __remove_const_t; + using mapped_type = typename _Tp::second_type; + }; + + template + struct __get_type<__hash_value_type<_Key, _Mapped> > { + using key_type = _Key; + using mapped_type = _Mapped; + }; + + using key_type = typename __get_type::key_type; + using mapped_type = typename __get_type::mapped_type; _LIBCPP_HIDE_FROM_ABI key_type& key() const { - return static_cast<_Derived const*>(this)->__ptr_->__get_value().__ref().first; + if constexpr (__is_specialization_v) { + return static_cast<_Derived const*>(this)->__ptr_->__get_value().__ref().first; + } else { + return const_cast(static_cast<_Derived const*>(this)->__ptr_->__get_value().first); + } } _LIBCPP_HIDE_FROM_ABI mapped_type& mapped() const { - return static_cast<_Derived const*>(this)->__ptr_->__get_value().__ref().second; + if constexpr (__is_specialization_v) { + return static_cast<_Derived const*>(this)->__ptr_->__get_value().__ref().second; + } else { + return static_cast<_Derived const*>(this)->__ptr_->__get_value().second; + } } }; diff --git a/libcxx/include/__tree b/libcxx/include/__tree index bbf7c71962e93..1903533898481 100644 --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -14,6 +14,7 @@ #include <__assert> #include <__config> #include <__fwd/map.h> +#include <__fwd/pair.h> #include <__fwd/set.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> @@ -25,6 +26,7 @@ #include <__memory/swap_allocator.h> #include <__memory/unique_ptr.h> #include <__type_traits/can_extract_key.h> +#include <__type_traits/copy_cvref.h> #include <__type_traits/enable_if.h> #include <__type_traits/invoke.h> #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 template struct __tree_key_value_types { typedef _Tp key_type; - typedef _Tp __node_value_type; typedef _Tp __container_value_type; static const bool __is_map = false; _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Tp const& __v) { return __v; } - _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __v) { return __v; } - _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { return std::addressof(__n); } - _LIBCPP_HIDE_FROM_ABI static __container_value_type&& __move(__node_value_type& __v) { return std::move(__v); } }; template struct __tree_key_value_types<__value_type<_Key, _Tp> > { typedef _Key key_type; typedef _Tp mapped_type; - typedef __value_type<_Key, _Tp> __node_value_type; typedef pair __container_value_type; typedef __container_value_type __map_value_type; static const bool __is_map = true; - _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(__node_value_type const& __t) { - return __t.__get_value().first; - } - template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Up& __t) { return __t.first; } - - _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __t) { - return __t.__get_value(); - } - - template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) { - return __t; - } - - _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { - return std::addressof(__n.__get_value()); - } - - _LIBCPP_HIDE_FROM_ABI static pair __move(__node_value_type& __v) { return __v.__move(); } }; template @@ -587,6 +565,19 @@ struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { typedef __rebind_pointer_t<_AllocPtr, const _Mv> __const_map_value_type_pointer; }; +template +struct __get_node_value_type { + using type _LIBCPP_NODEBUG = _Tp; +}; + +template +struct __get_node_value_type<__value_type<_Key, _ValueT> > { + using type _LIBCPP_NODEBUG = pair; +}; + +template +using __get_node_value_type_t _LIBCPP_NODEBUG = typename __get_node_value_type<_Tp>::type; + template ::element_type> struct __tree_node_types; @@ -599,7 +590,7 @@ public: typedef typename pointer_traits<_NodePtr>::element_type __node_type; typedef _NodePtr __node_pointer; - typedef _Tp __node_value_type; + using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>; typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer; typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer; @@ -650,11 +641,11 @@ public: template class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> { public: - typedef _Tp __node_value_type; + using __node_value_type _LIBCPP_NODEBUG = __get_node_value_type_t<_Tp>; __node_value_type __value_; - _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; } + _LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; } ~__tree_node() = delete; __tree_node(__tree_node const&) = delete; @@ -685,7 +676,7 @@ public: _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT { if (__value_constructed) - __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); + __alloc_traits::destroy(__na_, std::addressof(__p->__value_)); if (__p) __alloc_traits::deallocate(__na_, __p, 1); } @@ -715,7 +706,7 @@ class __tree_iterator { public: typedef bidirectional_iterator_tag iterator_category; - typedef _Tp value_type; + using value_type = __get_node_value_type_t<_Tp>; typedef _DiffType difference_type; typedef value_type& reference; typedef typename _NodeTypes::__node_value_type_pointer pointer; @@ -789,7 +780,7 @@ class __tree_const_iterator { public: typedef bidirectional_iterator_tag iterator_category; - typedef _Tp value_type; + using value_type = __get_node_value_type_t<_Tp>; typedef _DiffType difference_type; typedef const value_type& reference; typedef typename _NodeTypes::__const_node_value_type_pointer pointer; @@ -802,7 +793,7 @@ public: } private: - typedef __tree_iterator __non_const_iterator; + typedef __tree_iterator<_Tp, __node_pointer, difference_type> __non_const_iterator; public: _LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {} @@ -1107,6 +1098,18 @@ public: return __emplace_hint_unique(__p, std::forward<_Vp>(__v)); } + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI void + __insert_unique_from_orphaned_node(const_iterator __p, __get_node_value_type_t<_Tp>&& __value) { + using __key_type = typename _NodeTypes::key_type; + __emplace_hint_unique(__p, const_cast<__key_type&&>(__value.first), std::move(__value.second)); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(const_iterator __p, _Tp&& __value) { + __emplace_hint_unique(__p, std::move(__value)); + } + _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(__container_value_type&& __v) { return __emplace_multi(std::move(__v)); } @@ -1125,6 +1128,18 @@ public: return __emplace_hint_multi(__p, std::forward<_Vp>(__v)); } + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI void + __insert_multi_from_orphaned_node(const_iterator __p, __get_node_value_type_t<_Tp>&& __value) { + using __key_type = typename _NodeTypes::key_type; + __emplace_hint_multi(__p, const_cast<__key_type&&>(__value.first), std::move(__value.second)); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, _Tp&& __value) { + __emplace_hint_multi(__p, std::move(__value)); + } + _LIBCPP_HIDE_FROM_ABI pair __node_assign_unique(const __container_value_type& __v, __node_pointer __dest); @@ -1266,6 +1281,21 @@ private: } _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {} + template >, int> = 0> + _LIBCPP_HIDE_FROM_ABI static void __assign_value(__get_node_value_type_t& __lhs, _From&& __rhs) { + using __key_type = typename _NodeTypes::key_type; + + // This is technically UB, since the object was constructed as `const`. + // Clang doesn't optimize on this currently though. + const_cast<__key_type&>(__lhs.first) = const_cast<__copy_cvref_t<_From, __key_type>&&>(__rhs.first); + __lhs.second = std::forward<_From>(__rhs).second; + } + + template >, int> = 0> + _LIBCPP_HIDE_FROM_ABI static void __assign_value(_To& __lhs, _From&& __rhs) { + __lhs = std::forward<_From>(__rhs); + } + struct _DetachedTreeCache { _LIBCPP_HIDE_FROM_ABI explicit _DetachedTreeCache(__tree* __t) _NOEXCEPT : __t_(__t), @@ -1406,14 +1436,14 @@ void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _ if (size() != 0) { _DetachedTreeCache __cache(this); for (; __cache.__get() && __first != __last; ++__first) { - __cache.__get()->__value_ = *__first; + __assign_value(__cache.__get()->__value_, *__first); __node_insert_multi(__cache.__get()); __cache.__advance(); } } const_iterator __e = end(); for (; __first != __last; ++__first) - __insert_multi(__e, _NodeTypes::__get_value(*__first)); + __insert_multi(__e, *__first); } template @@ -1492,13 +1522,14 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) { if (size() != 0) { _DetachedTreeCache __cache(this); while (__cache.__get() != nullptr && __t.size() != 0) { - __cache.__get()->__value_ = std::move(__t.remove(__t.begin())->__value_); + __assign_value(__cache.__get()->__value_, std::move(__t.remove(__t.begin())->__value_)); __node_insert_multi(__cache.__get()); __cache.__advance(); } } - while (__t.size() != 0) - __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_)); + while (__t.size() != 0) { + __insert_multi_from_orphaned_node(__e, std::move(__t.remove(__t.begin())->__value_)); + } } } @@ -1524,7 +1555,7 @@ void __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT { destroy(static_cast<__node_pointer>(__nd->__left_)); destroy(static_cast<__node_pointer>(__nd->__right_)); __node_allocator& __na = __node_alloc(); - __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_)); + __node_traits::destroy(__na, std::addressof(__nd->__value_)); __node_traits::deallocate(__na, __nd, 1); } } @@ -1794,10 +1825,9 @@ template template typename __tree<_Tp, _Compare, _Allocator>::__node_holder __tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) { - static_assert(!__is_tree_value_type<_Args...>::value, "Cannot construct from __value_type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), std::forward<_Args>(__args)...); + __node_traits::construct(__na, std::addressof(__h->__value_), std::forward<_Args>(__args)...); __h.get_deleter().__value_constructed = true; return __h; } @@ -1865,7 +1895,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_ __node_pointer __r = static_cast<__node_pointer>(__child); bool __inserted = false; if (__child == nullptr) { - __nd->__value_ = __v; + __assign_value(__nd->__value_, __v); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); __r = __nd; __inserted = true; @@ -2027,7 +2057,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allo __node_pointer __np = __p.__get_np(); iterator __r = __remove_node_pointer(__np); __node_allocator& __na = __node_alloc(); - __node_traits::destroy(__na, _NodeTypes::__get_ptr(const_cast<__node_value_type&>(*__p))); + __node_traits::destroy(__na, std::addressof(const_cast<__node_value_type&>(*__p))); __node_traits::deallocate(__na, __np, 1); return __r; } diff --git a/libcxx/include/map b/libcxx/include/map index a244696295fb8..1f650d4f4c3d5 100644 --- a/libcxx/include/map +++ b/libcxx/include/map @@ -593,7 +593,6 @@ erase_if(multimap& c, Predicate pred); // C++20 # include <__memory/pointer_traits.h> # include <__memory/unique_ptr.h> # include <__memory_resource/polymorphic_allocator.h> -# include <__new/launder.h> # include <__node_handle> # include <__ranges/concepts.h> # include <__ranges/container_compatible_range.h> @@ -645,13 +644,13 @@ public: : _Compare(__c) {} _LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return *this; } _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const { - return static_cast(*this)(__x.__get_value().first, __y.__get_value().first); + return static_cast(*this)(__x.first, __y.first); } _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const { - return static_cast(*this)(__x.__get_value().first, __y); + return static_cast(*this)(__x.first, __y); } _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const { - return static_cast(*this)(__x, __y.__get_value().first); + return static_cast(*this)(__x, __y.first); } _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) { using std::swap; @@ -661,12 +660,12 @@ public: # if _LIBCPP_STD_VER >= 14 template _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const { - return static_cast(*this)(__x, __y.__get_value().first); + return static_cast(*this)(__x, __y.first); } template _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const { - return static_cast(*this)(__x.__get_value().first, __y); + return static_cast(*this)(__x.first, __y); } # endif }; @@ -682,15 +681,9 @@ public: : __comp_(__c) {} _LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return __comp_; } - _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const { - return __comp_(__x.__get_value().first, __y.__get_value().first); - } - _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const { - return __comp_(__x.__get_value().first, __y); - } - _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const { - return __comp_(__x, __y.__get_value().first); - } + _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const { return __comp_(__x.first, __y.first); } + _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const { return __comp_(__x.first, __y); } + _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const { return __comp_(__x, __y.first); } void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) { using std::swap; swap(__comp_, __y.__comp_); @@ -749,9 +742,9 @@ public: _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT { if (__second_constructed) - __alloc_traits::destroy(__na_, std::addressof(__p->__value_.__get_value().second)); + __alloc_traits::destroy(__na_, std::addressof(__p->__value_.second)); if (__first_constructed) - __alloc_traits::destroy(__na_, std::addressof(__p->__value_.__get_value().first)); + __alloc_traits::destroy(__na_, std::addressof(__p->__value_.first)); if (__p) __alloc_traits::deallocate(__na_, __p, 1); } @@ -760,90 +753,8 @@ public: template class __map_const_iterator; -# ifndef _LIBCPP_CXX03_LANG - template -struct _LIBCPP_STANDALONE_DEBUG __value_type { - typedef _Key key_type; - typedef _Tp mapped_type; - typedef pair value_type; - typedef pair __nc_ref_pair_type; - typedef pair __nc_rref_pair_type; - -private: - value_type __cc_; - -public: - _LIBCPP_HIDE_FROM_ABI value_type& __get_value() { -# if _LIBCPP_STD_VER >= 17 - return *std::launder(std::addressof(__cc_)); -# else - return __cc_; -# endif - } - - _LIBCPP_HIDE_FROM_ABI const value_type& __get_value() const { -# if _LIBCPP_STD_VER >= 17 - return *std::launder(std::addressof(__cc_)); -# else - return __cc_; -# endif - } - - _LIBCPP_HIDE_FROM_ABI __nc_ref_pair_type __ref() { - value_type& __v = __get_value(); - return __nc_ref_pair_type(const_cast(__v.first), __v.second); - } - - _LIBCPP_HIDE_FROM_ABI __nc_rref_pair_type __move() { - value_type& __v = __get_value(); - return __nc_rref_pair_type(std::move(const_cast(__v.first)), std::move(__v.second)); - } - - _LIBCPP_HIDE_FROM_ABI __value_type& operator=(const __value_type& __v) { - __ref() = __v.__get_value(); - return *this; - } - - _LIBCPP_HIDE_FROM_ABI __value_type& operator=(__value_type&& __v) { - __ref() = __v.__move(); - return *this; - } - - template ::value, int> = 0> - _LIBCPP_HIDE_FROM_ABI __value_type& operator=(_ValueTp&& __v) { - __ref() = std::forward<_ValueTp>(__v); - return *this; - } - - __value_type() = delete; - ~__value_type() = delete; - __value_type(const __value_type&) = delete; - __value_type(__value_type&&) = delete; -}; - -# else - -template -struct __value_type { - typedef _Key key_type; - typedef _Tp mapped_type; - typedef pair value_type; - -private: - value_type __cc_; - -public: - _LIBCPP_HIDE_FROM_ABI value_type& __get_value() { return __cc_; } - _LIBCPP_HIDE_FROM_ABI const value_type& __get_value() const { return __cc_; } - - __value_type() = delete; - __value_type(__value_type const&) = delete; - __value_type& operator=(__value_type const&) = delete; - ~__value_type() = delete; -}; - -# endif // _LIBCPP_CXX03_LANG +struct __value_type; template struct __extract_key_value_types; @@ -872,8 +783,8 @@ public: _LIBCPP_HIDE_FROM_ABI __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {} - _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __i_->__get_value(); } - _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits::pointer_to(__i_->__get_value()); } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__i_; } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits::pointer_to(*__i_); } _LIBCPP_HIDE_FROM_ABI __map_iterator& operator++() { ++__i_; @@ -930,8 +841,8 @@ public: _LIBCPP_HIDE_FROM_ABI __map_const_iterator(__map_iterator< typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT : __i_(__i.__i_) {} - _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __i_->__get_value(); } - _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits::pointer_to(__i_->__get_value()); } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__i_; } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits::pointer_to(*__i_); } _LIBCPP_HIDE_FROM_ABI __map_const_iterator& operator++() { ++__i_; @@ -999,7 +910,7 @@ public: private: typedef std::__value_type __value_type; - typedef __map_value_compare __vc; + typedef __map_value_compare __vc; typedef __rebind_alloc, __value_type> __allocator_type; typedef __tree<__value_type, __vc, __allocator_type> __base; typedef typename __base::__node_traits __node_traits; @@ -1305,7 +1216,7 @@ public: __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, std::move(__k), std::forward<_Vp>(__v)); if (!__inserted) - __r->__get_value().second = std::forward<_Vp>(__v); + __r->second = std::forward<_Vp>(__v); return __r; } @@ -1510,8 +1421,9 @@ map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), typename __base::allocator_type(__a)) { if (__a != __m.get_allocator()) { const_iterator __e = cend(); - while (!__m.empty()) - __tree_.__insert_unique(__e.__i_, __m.__tree_.remove(__m.begin().__i_)->__value_.__move()); + while (!__m.empty()) { + __tree_.__insert_unique_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_)); + } } } @@ -1519,8 +1431,7 @@ template _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) { return __tree_ .__emplace_unique_key_args(__k, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple()) - .first->__get_value() - .second; + .first->second; } template @@ -1530,8 +1441,7 @@ _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) { return __tree_ .__emplace_unique_key_args( __k, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple()) - .first->__get_value() - .second; + .first->second; // NOLINTEND(bugprone-use-after-move) } @@ -1542,9 +1452,9 @@ typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k) { __node_allocator& __na = __tree_.__node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, std::addressof(__h->__value_.__get_value().first), __k); + __node_traits::construct(__na, std::addressof(__h->__value_.first), __k); __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, std::addressof(__h->__value_.__get_value().second)); + __node_traits::construct(__na, std::addressof(__h->__value_.second)); __h.get_deleter().__second_constructed = true; return __h; } @@ -1559,7 +1469,7 @@ _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) { __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); __r = __h.release(); } - return __r->__value_.__get_value().second; + return __r->__value_.second; } # endif // _LIBCPP_CXX03_LANG @@ -1570,7 +1480,7 @@ _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) { __node_base_pointer& __child = __tree_.__find_equal(__parent, __k); if (__child == nullptr) std::__throw_out_of_range("map::at: key not found"); - return static_cast<__node_pointer>(__child)->__value_.__get_value().second; + return static_cast<__node_pointer>(__child)->__value_.second; } template @@ -1579,7 +1489,7 @@ const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const { __node_base_pointer __child = __tree_.__find_equal(__parent, __k); if (__child == nullptr) std::__throw_out_of_range("map::at: key not found"); - return static_cast<__node_pointer>(__child)->__value_.__get_value().second; + return static_cast<__node_pointer>(__child)->__value_.second; } template @@ -1685,7 +1595,7 @@ public: private: typedef std::__value_type __value_type; - typedef __map_value_compare __vc; + typedef __map_value_compare __vc; typedef __rebind_alloc, __value_type> __allocator_type; typedef __tree<__value_type, __vc, __allocator_type> __base; typedef typename __base::__node_traits __node_traits; @@ -2100,7 +2010,7 @@ multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const alloca if (__a != __m.get_allocator()) { const_iterator __e = cend(); while (!__m.empty()) - __tree_.__insert_multi(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__move())); + __tree_.__insert_multi_from_orphaned_node(__e.__i_, std::move(__m.__tree_.remove(__m.begin().__i_)->__value_)); } } # endif diff --git a/libcxx/test/libcxx/containers/associative/tree_key_value_traits.pass.cpp b/libcxx/test/libcxx/containers/associative/tree_key_value_traits.pass.cpp index e3a5a6f634138..04dcb8f54fafc 100644 --- a/libcxx/test/libcxx/containers/associative/tree_key_value_traits.pass.cpp +++ b/libcxx/test/libcxx/containers/associative/tree_key_value_traits.pass.cpp @@ -21,7 +21,6 @@ void testKeyValueTrait() { typedef int Tp; typedef std::__tree_key_value_types Traits; static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert(Traits::__is_map == false, ""); } @@ -29,7 +28,6 @@ void testKeyValueTrait() { typedef std::pair Tp; typedef std::__tree_key_value_types Traits; static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert(Traits::__is_map == false, ""); } @@ -37,7 +35,6 @@ void testKeyValueTrait() { typedef std::pair Tp; typedef std::__tree_key_value_types Traits; static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert(Traits::__is_map == false, ""); } @@ -46,7 +43,6 @@ void testKeyValueTrait() { typedef std::__tree_key_value_types Traits; static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); static_assert((std::is_same >::value), ""); static_assert((std::is_same >::value), ""); static_assert(Traits::__is_map == true, ""); diff --git a/libcxx/utils/gdb/libcxx/printers.py b/libcxx/utils/gdb/libcxx/printers.py index 31c27a1959cb2..e3d5d87aca325 100644 --- a/libcxx/utils/gdb/libcxx/printers.py +++ b/libcxx/utils/gdb/libcxx/printers.py @@ -673,7 +673,7 @@ def display_hint(self): return "map" def _get_key_value(self, node): - key_value = _cc_field(node.cast(self.util.cast_type).dereference()) + key_value = node.cast(self.util.cast_type).dereference()["__value_"] return [key_value["first"], key_value["second"]] @@ -738,7 +738,7 @@ def __init__(self, val): self._initialize(val["__i_"], _remove_generics(_prettify_typename(val.type))) def _get_node_value(self, node): - return _cc_field(node) + return node["__value_"] class SetIteratorPrinter(AbstractRBTreeIteratorPrinter):