@@ -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