@@ -122,6 +122,19 @@ struct __get_hash_node_value_type<__hash_value_type<_Key, _Tp> > {
122
122
template <class _Tp >
123
123
using __get_hash_node_value_type_t _LIBCPP_NODEBUG = typename __get_hash_node_value_type<_Tp>::type;
124
124
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
+
125
138
template <class _Tp , class _VoidPtr >
126
139
struct __hash_node : public __hash_node_base < __rebind_pointer_t <_VoidPtr, __hash_node<_Tp, _VoidPtr> > > {
127
140
using __node_value_type _LIBCPP_NODEBUG = __get_hash_node_value_type_t <_Tp>;
@@ -182,69 +195,11 @@ class __hash_map_iterator;
182
195
template <class _HashIterator >
183
196
class __hash_map_const_iterator ;
184
197
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
-
236
198
template <class _NodePtr , class _NodeT = typename pointer_traits<_NodePtr>::element_type>
237
199
struct __hash_node_types ;
238
200
239
201
template <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> > {
248
203
typedef ptrdiff_t difference_type;
249
204
typedef size_t size_type;
250
205
@@ -617,8 +572,6 @@ public:
617
572
typedef typename __alloc_traits::pointer pointer;
618
573
619
574
private:
620
- typedef __hash_node_types<pointer> _NodeTypes;
621
-
622
575
allocator_type& __na_;
623
576
624
577
public:
@@ -633,7 +586,7 @@ public:
633
586
634
587
_LIBCPP_HIDE_FROM_ABI void operator ()(pointer __p) _NOEXCEPT {
635
588
if (__value_constructed) {
636
- __alloc_traits::destroy (__na_, _NodeTypes::__get_ptr (__p->__get_value ()));
589
+ __alloc_traits::destroy (__na_, std::addressof (__p->__get_value ()));
637
590
std::__destroy_at (std::addressof (*__p));
638
591
}
639
592
if (__p)
@@ -684,6 +637,8 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
684
637
class __hash_table {
685
638
public:
686
639
using value_type = __get_hash_node_value_type_t <_Tp>;
640
+ using key_type = __get_hash_node_key_type_t <_Tp>;
641
+
687
642
typedef _Hash hasher;
688
643
typedef _Equal key_equal;
689
644
typedef _Alloc allocator_type;
@@ -694,8 +649,6 @@ private:
694
649
695
650
public:
696
651
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;
699
652
typedef value_type& reference;
700
653
typedef const value_type& const_reference;
701
654
typedef typename __alloc_traits::pointer pointer;
@@ -824,7 +777,7 @@ public:
824
777
825
778
template <class _First ,
826
779
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 >
828
781
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool > __emplace_unique (_First&& __f, _Second&& __s) {
829
782
return __emplace_unique_key_args (__f, std::forward<_First>(__f), std::forward<_Second>(__s));
830
783
}
@@ -854,9 +807,7 @@ public:
854
807
855
808
template <class _ValueT = _Tp, __enable_if_t <__is_hash_value_type<_ValueT>::value, int > = 0 >
856
809
_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 ));
860
811
__node_insert_unique (__h.get ());
861
812
__h.release ();
862
813
}
@@ -870,9 +821,7 @@ public:
870
821
871
822
template <class _ValueT = _Tp, __enable_if_t <__is_hash_value_type<_ValueT>::value, int > = 0 >
872
823
_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 ));
876
825
__node_insert_multi (__h.get ());
877
826
__h.release ();
878
827
}
@@ -1047,12 +996,10 @@ private:
1047
996
1048
997
template <class _From , class _ValueT = _Tp, __enable_if_t <__is_hash_value_type<_ValueT>::value, int > = 0 >
1049
998
_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
-
1052
999
// This is technically UB, since the object was constructed as `const`.
1053
1000
// 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 ;
1056
1003
}
1057
1004
1058
1005
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
1201
1148
while (__np != nullptr ) {
1202
1149
__next_pointer __next = __np->__next_ ;
1203
1150
__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 ()));
1205
1152
std::__destroy_at (std::addressof (*__real_np));
1206
1153
__node_traits::deallocate (__na, __real_np, 1 );
1207
1154
__np = __next;
@@ -1290,8 +1237,8 @@ template <class _InputIterator>
1290
1237
void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique (_InputIterator __first, _InputIterator __last) {
1291
1238
typedef iterator_traits<_InputIterator> _ITraits;
1292
1239
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" );
1295
1242
1296
1243
if (bucket_count () != 0 ) {
1297
1244
__next_pointer __cache = __detach ();
@@ -1321,10 +1268,8 @@ template <class _InputIterator>
1321
1268
void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi (_InputIterator __first, _InputIterator __last) {
1322
1269
typedef iterator_traits<_InputIterator> _ITraits;
1323
1270
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" );
1328
1273
if (bucket_count () != 0 ) {
1329
1274
__next_pointer __cache = __detach ();
1330
1275
#if _LIBCPP_HAS_EXCEPTIONS
@@ -1345,7 +1290,7 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __f
1345
1290
__deallocate_node (__cache);
1346
1291
}
1347
1292
for (; __first != __last; ++__first)
1348
- __emplace_multi (_NodeTypes::__get_value ( *__first) );
1293
+ __emplace_multi (*__first);
1349
1294
}
1350
1295
1351
1296
template <class _Tp , class _Hash , class _Equal , class _Alloc >
@@ -1863,7 +1808,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&&... __args) {
1863
1808
std::__construct_at (std::addressof (*__h), /* next = */ nullptr , /* hash = */ 0 );
1864
1809
1865
1810
// 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)...);
1867
1812
__h.get_deleter ().__value_constructed = true ;
1868
1813
1869
1814
__h->__hash_ = hash_function ()(__h->__get_value ());
@@ -1879,7 +1824,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, _
1879
1824
__node_holder __h (__node_traits::allocate (__na, 1 ), _Dp (__na));
1880
1825
std::__construct_at (std::addressof (*__h), /* next = */ nullptr , /* hash = */ __hash);
1881
1826
__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)...);
1883
1828
__h.get_deleter ().__value_constructed = true ;
1884
1829
return __h;
1885
1830
}
0 commit comments