Skip to content

Commit b8b99d8

Browse files
authored
[libc++] Simplify __hash_table further (#148375)
1 parent a13712e commit b8b99d8

File tree

3 files changed

+34
-149
lines changed

3 files changed

+34
-149
lines changed

libcxx/include/__hash_table

Lines changed: 30 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,19 @@ struct __get_hash_node_value_type<__hash_value_type<_Key, _Tp> > {
122122
template <class _Tp>
123123
using __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+
125138
template <class _Tp, class _VoidPtr>
126139
struct __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;
182195
template <class _HashIterator>
183196
class __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-
236198
template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
237199
struct __hash_node_types;
238200

239201
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> > {
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

619574
private:
620-
typedef __hash_node_types<pointer> _NodeTypes;
621-
622575
allocator_type& __na_;
623576

624577
public:
@@ -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>
684637
class __hash_table {
685638
public:
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

695650
public:
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>
12901237
void __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>
13211268
void __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

13511296
template <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
}

libcxx/include/unordered_map

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -844,10 +844,10 @@ class __hash_map_iterator {
844844

845845
public:
846846
typedef forward_iterator_tag iterator_category;
847-
typedef typename _NodeTypes::__map_value_type value_type;
847+
using value_type = typename _HashIterator::value_type;
848848
typedef typename _NodeTypes::difference_type difference_type;
849849
typedef value_type& reference;
850-
typedef typename _NodeTypes::__map_value_type_pointer pointer;
850+
using pointer = typename _HashIterator::pointer;
851851

852852
_LIBCPP_HIDE_FROM_ABI __hash_map_iterator() _NOEXCEPT {}
853853

@@ -895,10 +895,10 @@ class __hash_map_const_iterator {
895895

896896
public:
897897
typedef forward_iterator_tag iterator_category;
898-
typedef typename _NodeTypes::__map_value_type value_type;
898+
using value_type = typename _HashIterator::value_type;
899899
typedef typename _NodeTypes::difference_type difference_type;
900900
typedef const value_type& reference;
901-
typedef typename _NodeTypes::__const_map_value_type_pointer pointer;
901+
using pointer = typename _HashIterator::pointer;
902902

903903
_LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator() _NOEXCEPT {}
904904

libcxx/test/libcxx/containers/unord/key_value_traits.pass.cpp

Lines changed: 0 additions & 60 deletions
This file was deleted.

0 commit comments

Comments
 (0)