Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 30 additions & 85 deletions libcxx/include/__hash_table
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,19 @@ struct __get_hash_node_value_type<__hash_value_type<_Key, _Tp> > {
template <class _Tp>
using __get_hash_node_value_type_t _LIBCPP_NODEBUG = typename __get_hash_node_value_type<_Tp>::type;

template <class _Tp>
struct __get_hash_node_key_type {
using type _LIBCPP_NODEBUG = _Tp;
};

template <class _Key, class _Tp>
struct __get_hash_node_key_type<__hash_value_type<_Key, _Tp> > {
using type _LIBCPP_NODEBUG = _Key;
};

template <class _Tp>
using __get_hash_node_key_type_t _LIBCPP_NODEBUG = typename __get_hash_node_key_type<_Tp>::type;

template <class _Tp, class _VoidPtr>
struct __hash_node : public __hash_node_base< __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > > {
using __node_value_type _LIBCPP_NODEBUG = __get_hash_node_value_type_t<_Tp>;
Expand Down Expand Up @@ -182,69 +195,11 @@ class __hash_map_iterator;
template <class _HashIterator>
class __hash_map_const_iterator;

template <class _Tp>
struct __hash_key_value_types {
static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");
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 <class _Key, class _Tp>
struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
typedef _Key key_type;
typedef _Tp mapped_type;
typedef __hash_value_type<_Key, _Tp> __node_value_type;
typedef pair<const _Key, _Tp> __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(__container_value_type const& __v) { return __v.first; }

template <class _Up, __enable_if_t<is_same<__remove_cvref_t<_Up>, __node_value_type>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) {
return __t.__get_value();
}

template <class _Up, __enable_if_t<is_same<__remove_cvref_t<_Up>, __container_value_type>::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(__container_value_type& __n) {
return std::addressof(__n);
}
_LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { return __v.__move(); }
};

template <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>, bool = _KVTypes::__is_map>
struct __hash_map_pointer_types {};

template <class _Tp, class _AllocPtr, class _KVTypes>
struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
typedef typename _KVTypes::__map_value_type _Mv;
typedef __rebind_pointer_t<_AllocPtr, _Mv> __map_value_type_pointer;
typedef __rebind_pointer_t<_AllocPtr, const _Mv> __const_map_value_type_pointer;
};

template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
struct __hash_node_types;

template <class _NodePtr, class _Tp, class _VoidPtr>
struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> >
: public __hash_key_value_types<_Tp>,
__hash_map_pointer_types<_Tp, _VoidPtr>

{
typedef __hash_key_value_types<_Tp> __base;

public:
struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > {
typedef ptrdiff_t difference_type;
typedef size_t size_type;

Expand Down Expand Up @@ -617,8 +572,6 @@ public:
typedef typename __alloc_traits::pointer pointer;

private:
typedef __hash_node_types<pointer> _NodeTypes;

allocator_type& __na_;

public:
Expand All @@ -633,7 +586,7 @@ public:

_LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
if (__value_constructed) {
__alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__get_value()));
__alloc_traits::destroy(__na_, std::addressof(__p->__get_value()));
std::__destroy_at(std::addressof(*__p));
}
if (__p)
Expand Down Expand Up @@ -684,6 +637,8 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
class __hash_table {
public:
using value_type = __get_hash_node_value_type_t<_Tp>;
using key_type = __get_hash_node_key_type_t<_Tp>;

typedef _Hash hasher;
typedef _Equal key_equal;
typedef _Alloc allocator_type;
Expand All @@ -694,8 +649,6 @@ private:

public:
typedef typename _NodeTypes::__node_value_type __node_value_type;
typedef typename _NodeTypes::__container_value_type __container_value_type;
typedef typename _NodeTypes::key_type key_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename __alloc_traits::pointer pointer;
Expand Down Expand Up @@ -824,7 +777,7 @@ public:

template <class _First,
class _Second,
__enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, int> = 0>
__enable_if_t<__can_extract_map_key<_First, key_type, value_type>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique(_First&& __f, _Second&& __s) {
return __emplace_unique_key_args(__f, std::forward<_First>(__f), std::forward<_Second>(__s));
}
Expand Down Expand Up @@ -854,9 +807,7 @@ public:

template <class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI void __insert_unique_from_orphaned_node(value_type&& __value) {
using __key_type = typename _NodeTypes::key_type;

__node_holder __h = __construct_node(const_cast<__key_type&&>(__value.first), std::move(__value.second));
__node_holder __h = __construct_node(const_cast<key_type&&>(__value.first), std::move(__value.second));
__node_insert_unique(__h.get());
__h.release();
}
Expand All @@ -870,9 +821,7 @@ public:

template <class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(value_type&& __value) {
using __key_type = typename _NodeTypes::key_type;

__node_holder __h = __construct_node(const_cast<__key_type&&>(__value.first), std::move(__value.second));
__node_holder __h = __construct_node(const_cast<key_type&&>(__value.first), std::move(__value.second));
__node_insert_multi(__h.get());
__h.release();
}
Expand Down Expand Up @@ -1047,12 +996,10 @@ private:

template <class _From, class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI void __assign_value(__get_hash_node_value_type_t<_Tp>& __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;
const_cast<key_type&>(__lhs.first) = const_cast<__copy_cvref_t<_From, key_type>&&>(__rhs.first);
__lhs.second = std::forward<_From>(__rhs).second;
}

template <class _From, class _ValueT = _Tp, __enable_if_t<!__is_hash_value_type<_ValueT>::value, int> = 0>
Expand Down Expand Up @@ -1201,7 +1148,7 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer
while (__np != nullptr) {
__next_pointer __next = __np->__next_;
__node_pointer __real_np = __np->__upcast();
__node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__get_value()));
__node_traits::destroy(__na, std::addressof(__real_np->__get_value()));
std::__destroy_at(std::addressof(*__real_np));
__node_traits::deallocate(__na, __real_np, 1);
__np = __next;
Expand Down Expand Up @@ -1290,8 +1237,8 @@ template <class _InputIterator>
void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, _InputIterator __last) {
typedef iterator_traits<_InputIterator> _ITraits;
typedef typename _ITraits::value_type _ItValueType;
static_assert(is_same<_ItValueType, __container_value_type>::value,
"__assign_unique may only be called with the containers value type");
static_assert(
is_same<_ItValueType, value_type>::value, "__assign_unique may only be called with the containers value type");

if (bucket_count() != 0) {
__next_pointer __cache = __detach();
Expand Down Expand Up @@ -1321,10 +1268,8 @@ template <class _InputIterator>
void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, _InputIterator __last) {
typedef iterator_traits<_InputIterator> _ITraits;
typedef typename _ITraits::value_type _ItValueType;
static_assert(
(is_same<_ItValueType, __container_value_type>::value || is_same<_ItValueType, __node_value_type>::value),
"__assign_multi may only be called with the containers value type"
" or the nodes value type");
static_assert(is_same<_ItValueType, value_type>::value,
"__assign_multi may only be called with the containers value type or the nodes value type");
if (bucket_count() != 0) {
__next_pointer __cache = __detach();
#if _LIBCPP_HAS_EXCEPTIONS
Expand All @@ -1345,7 +1290,7 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __f
__deallocate_node(__cache);
}
for (; __first != __last; ++__first)
__emplace_multi(_NodeTypes::__get_value(*__first));
__emplace_multi(*__first);
}

template <class _Tp, class _Hash, class _Equal, class _Alloc>
Expand Down Expand Up @@ -1863,7 +1808,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&&... __args) {
std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ 0);

// Now construct the value_type using the allocator's construct() method.
__node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_Args>(__args)...);
__node_traits::construct(__na, std::addressof(__h->__get_value()), std::forward<_Args>(__args)...);
__h.get_deleter().__value_constructed = true;

__h->__hash_ = hash_function()(__h->__get_value());
Expand All @@ -1879,7 +1824,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, _
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ __hash);
__node_traits::construct(
__na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_First>(__f), std::forward<_Rest>(__rest)...);
__na, std::addressof(__h->__get_value()), std::forward<_First>(__f), std::forward<_Rest>(__rest)...);
__h.get_deleter().__value_constructed = true;
return __h;
}
Expand Down
8 changes: 4 additions & 4 deletions libcxx/include/unordered_map
Original file line number Diff line number Diff line change
Expand Up @@ -844,10 +844,10 @@ class __hash_map_iterator {

public:
typedef forward_iterator_tag iterator_category;
typedef typename _NodeTypes::__map_value_type value_type;
using value_type = typename _HashIterator::value_type;
typedef typename _NodeTypes::difference_type difference_type;
typedef value_type& reference;
typedef typename _NodeTypes::__map_value_type_pointer pointer;
using pointer = typename _HashIterator::pointer;

_LIBCPP_HIDE_FROM_ABI __hash_map_iterator() _NOEXCEPT {}

Expand Down Expand Up @@ -895,10 +895,10 @@ class __hash_map_const_iterator {

public:
typedef forward_iterator_tag iterator_category;
typedef typename _NodeTypes::__map_value_type value_type;
using value_type = typename _HashIterator::value_type;
typedef typename _NodeTypes::difference_type difference_type;
typedef const value_type& reference;
typedef typename _NodeTypes::__const_map_value_type_pointer pointer;
using pointer = typename _HashIterator::pointer;

_LIBCPP_HIDE_FROM_ABI __hash_map_const_iterator() _NOEXCEPT {}

Expand Down
60 changes: 0 additions & 60 deletions libcxx/test/libcxx/containers/unord/key_value_traits.pass.cpp

This file was deleted.

Loading