@@ -122,6 +122,19 @@ struct __get_hash_node_value_type<__hash_value_type<_Key, _Tp> > {
122122template <class _Tp >
123123using __get_hash_node_value_type_t _LIBCPP_NODEBUG = typename __get_hash_node_value_type<_Tp>::type;
124124
125+ template <class _Tp >
126+ struct __get_hash_node_key_type {
127+ using type _LIBCPP_NODEBUG = _Tp;
128+ };
129+
130+ template <class _Key , class _Tp >
131+ struct __get_hash_node_key_type <__hash_value_type<_Key, _Tp> > {
132+ using type _LIBCPP_NODEBUG = _Key;
133+ };
134+
135+ template <class _Tp >
136+ using __get_hash_node_key_type_t _LIBCPP_NODEBUG = typename __get_hash_node_key_type<_Tp>::type;
137+
125138template <class _Tp , class _VoidPtr >
126139struct __hash_node : public __hash_node_base < __rebind_pointer_t <_VoidPtr, __hash_node<_Tp, _VoidPtr> > > {
127140 using __node_value_type _LIBCPP_NODEBUG = __get_hash_node_value_type_t <_Tp>;
@@ -182,69 +195,11 @@ class __hash_map_iterator;
182195template <class _HashIterator >
183196class __hash_map_const_iterator ;
184197
185- template <class _Tp >
186- struct __hash_key_value_types {
187- static_assert (!is_reference<_Tp>::value && !is_const<_Tp>::value, " " );
188- typedef _Tp key_type;
189- typedef _Tp __node_value_type;
190- typedef _Tp __container_value_type;
191- static const bool __is_map = false ;
192-
193- _LIBCPP_HIDE_FROM_ABI static key_type const & __get_key (_Tp const & __v) { return __v; }
194- _LIBCPP_HIDE_FROM_ABI static __container_value_type const & __get_value (__node_value_type const & __v) { return __v; }
195- _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr (__node_value_type& __n) { return std::addressof (__n); }
196- _LIBCPP_HIDE_FROM_ABI static __container_value_type&& __move(__node_value_type& __v) { return std::move (__v); }
197- };
198-
199- template <class _Key , class _Tp >
200- struct __hash_key_value_types <__hash_value_type<_Key, _Tp> > {
201- typedef _Key key_type;
202- typedef _Tp mapped_type;
203- typedef __hash_value_type<_Key, _Tp> __node_value_type;
204- typedef pair<const _Key, _Tp> __container_value_type;
205- typedef __container_value_type __map_value_type;
206- static const bool __is_map = true ;
207-
208- _LIBCPP_HIDE_FROM_ABI static key_type const & __get_key (__container_value_type const & __v) { return __v.first ; }
209-
210- template <class _Up , __enable_if_t <is_same<__remove_cvref_t <_Up>, __node_value_type>::value, int > = 0 >
211- _LIBCPP_HIDE_FROM_ABI static __container_value_type const & __get_value (_Up& __t ) {
212- return __t .__get_value ();
213- }
214-
215- template <class _Up , __enable_if_t <is_same<__remove_cvref_t <_Up>, __container_value_type>::value, int > = 0 >
216- _LIBCPP_HIDE_FROM_ABI static __container_value_type const & __get_value (_Up& __t ) {
217- return __t ;
218- }
219-
220- _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr (__container_value_type& __n) {
221- return std::addressof (__n);
222- }
223- _LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move (__node_value_type& __v) { return __v.__move (); }
224- };
225-
226- template <class _Tp , class _AllocPtr , class _KVTypes = __hash_key_value_types<_Tp>, bool = _KVTypes::__is_map>
227- struct __hash_map_pointer_types {};
228-
229- template <class _Tp , class _AllocPtr , class _KVTypes >
230- struct __hash_map_pointer_types <_Tp, _AllocPtr, _KVTypes, true > {
231- typedef typename _KVTypes::__map_value_type _Mv;
232- typedef __rebind_pointer_t <_AllocPtr, _Mv> __map_value_type_pointer;
233- typedef __rebind_pointer_t <_AllocPtr, const _Mv> __const_map_value_type_pointer;
234- };
235-
236198template <class _NodePtr , class _NodeT = typename pointer_traits<_NodePtr>::element_type>
237199struct __hash_node_types ;
238200
239201template <class _NodePtr , class _Tp , class _VoidPtr >
240- struct __hash_node_types <_NodePtr, __hash_node<_Tp, _VoidPtr> >
241- : public __hash_key_value_types<_Tp>,
242- __hash_map_pointer_types<_Tp, _VoidPtr>
243-
244- {
245- typedef __hash_key_value_types<_Tp> __base;
246-
247- public:
202+ struct __hash_node_types <_NodePtr, __hash_node<_Tp, _VoidPtr> > {
248203 typedef ptrdiff_t difference_type;
249204 typedef size_t size_type;
250205
@@ -617,8 +572,6 @@ public:
617572 typedef typename __alloc_traits::pointer pointer;
618573
619574private:
620- typedef __hash_node_types<pointer> _NodeTypes;
621-
622575 allocator_type& __na_;
623576
624577public:
@@ -633,7 +586,7 @@ public:
633586
634587 _LIBCPP_HIDE_FROM_ABI void operator ()(pointer __p) _NOEXCEPT {
635588 if (__value_constructed) {
636- __alloc_traits::destroy (__na_, _NodeTypes::__get_ptr (__p->__get_value ()));
589+ __alloc_traits::destroy (__na_, std::addressof (__p->__get_value ()));
637590 std::__destroy_at (std::addressof (*__p));
638591 }
639592 if (__p)
@@ -684,6 +637,8 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
684637class __hash_table {
685638public:
686639 using value_type = __get_hash_node_value_type_t <_Tp>;
640+ using key_type = __get_hash_node_key_type_t <_Tp>;
641+
687642 typedef _Hash hasher;
688643 typedef _Equal key_equal;
689644 typedef _Alloc allocator_type;
@@ -694,8 +649,6 @@ private:
694649
695650public:
696651 typedef typename _NodeTypes::__node_value_type __node_value_type;
697- typedef typename _NodeTypes::__container_value_type __container_value_type;
698- typedef typename _NodeTypes::key_type key_type;
699652 typedef value_type& reference;
700653 typedef const value_type& const_reference;
701654 typedef typename __alloc_traits::pointer pointer;
@@ -824,7 +777,7 @@ public:
824777
825778 template <class _First ,
826779 class _Second ,
827- __enable_if_t <__can_extract_map_key<_First, key_type, __container_value_type >::value, int > = 0 >
780+ __enable_if_t <__can_extract_map_key<_First, key_type, value_type >::value, int > = 0 >
828781 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool > __emplace_unique (_First&& __f, _Second&& __s) {
829782 return __emplace_unique_key_args (__f, std::forward<_First>(__f), std::forward<_Second>(__s));
830783 }
@@ -854,9 +807,7 @@ public:
854807
855808 template <class _ValueT = _Tp, __enable_if_t <__is_hash_value_type<_ValueT>::value, int > = 0 >
856809 _LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node (value_type&& __value) {
857- using __key_type = typename _NodeTypes::key_type;
858-
859- __node_holder __h = __construct_node (const_cast <__key_type&&>(__value.first ), std::move (__value.second ));
810+ __node_holder __h = __construct_node (const_cast <key_type&&>(__value.first ), std::move (__value.second ));
860811 __node_insert_unique (__h.get ());
861812 __h.release ();
862813 }
@@ -870,9 +821,7 @@ public:
870821
871822 template <class _ValueT = _Tp, __enable_if_t <__is_hash_value_type<_ValueT>::value, int > = 0 >
872823 _LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node (value_type&& __value) {
873- using __key_type = typename _NodeTypes::key_type;
874-
875- __node_holder __h = __construct_node (const_cast <__key_type&&>(__value.first ), std::move (__value.second ));
824+ __node_holder __h = __construct_node (const_cast <key_type&&>(__value.first ), std::move (__value.second ));
876825 __node_insert_multi (__h.get ());
877826 __h.release ();
878827 }
@@ -1047,12 +996,10 @@ private:
1047996
1048997 template <class _From , class _ValueT = _Tp, __enable_if_t <__is_hash_value_type<_ValueT>::value, int > = 0 >
1049998 _LIBCPP_HIDE_FROM_ABI void __assign_value (__get_hash_node_value_type_t <_Tp>& __lhs, _From&& __rhs) {
1050- using __key_type = typename _NodeTypes::key_type;
1051-
1052999 // This is technically UB, since the object was constructed as `const`.
10531000 // Clang doesn't optimize on this currently though.
1054- const_cast <__key_type &>(__lhs.first ) = const_cast <__copy_cvref_t <_From, __key_type >&&>(__rhs.first );
1055- __lhs.second = std::forward<_From>(__rhs).second ;
1001+ const_cast <key_type &>(__lhs.first ) = const_cast <__copy_cvref_t <_From, key_type >&&>(__rhs.first );
1002+ __lhs.second = std::forward<_From>(__rhs).second ;
10561003 }
10571004
10581005 template <class _From , class _ValueT = _Tp, __enable_if_t <!__is_hash_value_type<_ValueT>::value, int > = 0 >
@@ -1201,7 +1148,7 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer
12011148 while (__np != nullptr ) {
12021149 __next_pointer __next = __np->__next_ ;
12031150 __node_pointer __real_np = __np->__upcast ();
1204- __node_traits::destroy (__na, _NodeTypes::__get_ptr (__real_np->__get_value ()));
1151+ __node_traits::destroy (__na, std::addressof (__real_np->__get_value ()));
12051152 std::__destroy_at (std::addressof (*__real_np));
12061153 __node_traits::deallocate (__na, __real_np, 1 );
12071154 __np = __next;
@@ -1290,8 +1237,8 @@ template <class _InputIterator>
12901237void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique (_InputIterator __first, _InputIterator __last) {
12911238 typedef iterator_traits<_InputIterator> _ITraits;
12921239 typedef typename _ITraits::value_type _ItValueType;
1293- static_assert (is_same<_ItValueType, __container_value_type>::value,
1294- " __assign_unique may only be called with the containers value type" );
1240+ static_assert (
1241+ is_same<_ItValueType, value_type>::value, " __assign_unique may only be called with the containers value type" );
12951242
12961243 if (bucket_count () != 0 ) {
12971244 __next_pointer __cache = __detach ();
@@ -1321,10 +1268,8 @@ template <class _InputIterator>
13211268void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi (_InputIterator __first, _InputIterator __last) {
13221269 typedef iterator_traits<_InputIterator> _ITraits;
13231270 typedef typename _ITraits::value_type _ItValueType;
1324- static_assert (
1325- (is_same<_ItValueType, __container_value_type>::value || is_same<_ItValueType, __node_value_type>::value),
1326- " __assign_multi may only be called with the containers value type"
1327- " or the nodes value type" );
1271+ static_assert (is_same<_ItValueType, value_type>::value,
1272+ " __assign_multi may only be called with the containers value type or the nodes value type" );
13281273 if (bucket_count () != 0 ) {
13291274 __next_pointer __cache = __detach ();
13301275#if _LIBCPP_HAS_EXCEPTIONS
@@ -1345,7 +1290,7 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __f
13451290 __deallocate_node (__cache);
13461291 }
13471292 for (; __first != __last; ++__first)
1348- __emplace_multi (_NodeTypes::__get_value ( *__first) );
1293+ __emplace_multi (*__first);
13491294}
13501295
13511296template <class _Tp , class _Hash , class _Equal , class _Alloc >
@@ -1863,7 +1808,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&&... __args) {
18631808 std::__construct_at (std::addressof (*__h), /* next = */ nullptr , /* hash = */ 0 );
18641809
18651810 // Now construct the value_type using the allocator's construct() method.
1866- __node_traits::construct (__na, _NodeTypes::__get_ptr (__h->__get_value ()), std::forward<_Args>(__args)...);
1811+ __node_traits::construct (__na, std::addressof (__h->__get_value ()), std::forward<_Args>(__args)...);
18671812 __h.get_deleter ().__value_constructed = true ;
18681813
18691814 __h->__hash_ = hash_function ()(__h->__get_value ());
@@ -1879,7 +1824,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, _
18791824 __node_holder __h (__node_traits::allocate (__na, 1 ), _Dp (__na));
18801825 std::__construct_at (std::addressof (*__h), /* next = */ nullptr , /* hash = */ __hash);
18811826 __node_traits::construct (
1882- __na, _NodeTypes::__get_ptr (__h->__get_value ()), std::forward<_First>(__f), std::forward<_Rest>(__rest)...);
1827+ __na, std::addressof (__h->__get_value ()), std::forward<_First>(__f), std::forward<_Rest>(__rest)...);
18831828 __h.get_deleter ().__value_constructed = true ;
18841829 return __h;
18851830}
0 commit comments