Skip to content

map, unordered_map: use static method for getting value of __hash_value_type #135365

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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
4 changes: 2 additions & 2 deletions libcxx/include/__cxx03/__hash_table
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't modify the C++03 headers.

Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {

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

template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, int> = 0>
Expand All @@ -192,7 +192,7 @@ struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > {
}

_LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) {
return std::addressof(__n.__get_value());
return std::addressof(__node_value_type::__get_value(__n));
}
_LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { return __v.__move(); }
};
Expand Down
6 changes: 3 additions & 3 deletions libcxx/include/__cxx03/__tree
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ struct __tree_key_value_types<__value_type<_Key, _Tp> > {
static const bool __is_map = true;

_LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(__node_value_type const& __t) {
return __t.__get_value().first;
return __node_value_type::__get_value(__t).first;
}

template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, int> = 0>
Expand All @@ -542,7 +542,7 @@ struct __tree_key_value_types<__value_type<_Key, _Tp> > {
}

_LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __t) {
return __t.__get_value();
return __node_value_type::__get_value(__t);
}

template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, int> = 0>
Expand All @@ -551,7 +551,7 @@ struct __tree_key_value_types<__value_type<_Key, _Tp> > {
}

_LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) {
return std::addressof(__n.__get_value());
return std::addressof(__node_value_type::__get_value(__n));
}

_LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { return __v.__move(); }
Expand Down
98 changes: 57 additions & 41 deletions libcxx/include/__cxx03/map
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
#include <__cxx03/__memory/allocator.h>
#include <__cxx03/__tree>
#include <__cxx03/__type_traits/is_allocator.h>
#include <__cxx03/__type_traits/is_standard_layout.h>
#include <__cxx03/__utility/forward.h>
#include <__cxx03/__utility/piecewise_construct.h>
#include <__cxx03/__utility/swap.h>
Expand Down Expand Up @@ -616,13 +617,13 @@ public:
: _Compare(__c) {}
_LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return *this; }
_LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const {
return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y.__get_value().first);
return static_cast<const _Compare&>(*this)(_CP::__get_value(__x).first, _CP::__get_value(__y).first);
}
_LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const {
return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);
return static_cast<const _Compare&>(*this)(_CP::__get_value(__x).first, __y);
}
_LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const {
return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);
return static_cast<const _Compare&>(*this)(__x, _CP::__get_value(__y).first);
}
_LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {
using std::swap;
Expand All @@ -632,12 +633,12 @@ public:
#if _LIBCPP_STD_VER >= 14
template <typename _K2>
_LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {
return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);
return static_cast<const _Compare&>(*this)(__x, _CP::__get_value(__y).first);
}

template <typename _K2>
_LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {
return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);
return static_cast<const _Compare&>(*this)(_CP::__get_value(__x).first, __y);
}
#endif
};
Expand All @@ -654,13 +655,13 @@ public:
_LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return __comp_; }

_LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const {
return __comp_(__x.__get_value().first, __y.__get_value().first);
return __comp_(_CP::__get_value(__x).first, _CP::__get_value(__y).first);
}
_LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const {
return __comp_(__x.__get_value().first, __y);
return __comp_(_CP::__get_value(__x).first, __y);
}
_LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const {
return __comp_(__x, __y.__get_value().first);
return __comp_(__x, _CP::__get_value(__y).first);
}
void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {
using std::swap;
Expand All @@ -670,12 +671,12 @@ public:
#if _LIBCPP_STD_VER >= 14
template <typename _K2>
_LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {
return __comp_(__x, __y.__get_value().first);
return __comp_(__x, _CP::__get_value(__y).first);
}

template <typename _K2>
_LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {
return __comp_(__x.__get_value().first, __y);
return __comp_(_CP::__get_value(__x).first, __y);
}
#endif
};
Expand All @@ -691,6 +692,7 @@ template <class _Allocator>
class __map_node_destructor {
typedef _Allocator allocator_type;
typedef allocator_traits<allocator_type> __alloc_traits;
typedef __alloc_traits::value_type value_type;

public:
typedef typename __alloc_traits::pointer pointer;
Expand Down Expand Up @@ -720,9 +722,9 @@ public:

_LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
if (__second_constructed)
__alloc_traits::destroy(__na_, std::addressof(__p->__value_.__get_value().second));
__alloc_traits::destroy(__na_, std::addressof(value_type::__get_value(__p->__value_).second));
if (__first_constructed)
__alloc_traits::destroy(__na_, std::addressof(__p->__value_.__get_value().first));
__alloc_traits::destroy(__na_, std::addressof(value_type::__get_value(__p->__value_).first));
if (__p)
__alloc_traits::deallocate(__na_, __p, 1);
}
Expand All @@ -749,34 +751,34 @@ private:
value_type __cc_;

public:
_LIBCPP_HIDE_FROM_ABI value_type& __get_value() {
_LIBCPP_HIDE_FROM_ABI static value_type& __get_value(__hash_value_type& __v) {
# if _LIBCPP_STD_VER >= 17
return *std::launder(std::addressof(__cc_));
return *std::launder(std::addressof(reinterpret_cast<const value_type&>(__v)));
# else
return __cc_;
return reinterpret_cast<const value_type&>(__v);
# endif
}

_LIBCPP_HIDE_FROM_ABI const value_type& __get_value() const {
_LIBCPP_HIDE_FROM_ABI static const value_type& __get_value(const __hash_value_type& __v) {
# if _LIBCPP_STD_VER >= 17
return *std::launder(std::addressof(__cc_));
return *std::launder(std::addressof(reinterpret_cast<value_type&>(__v)));
# else
return __cc_;
return reinterpret_cast<value_type&>(__v);
# endif
}

_LIBCPP_HIDE_FROM_ABI __nc_ref_pair_type __ref() {
value_type& __v = __get_value();
value_type& __v = __get_value(*this);
return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second);
}

_LIBCPP_HIDE_FROM_ABI __nc_rref_pair_type __move() {
value_type& __v = __get_value();
value_type& __v = __get_value(*this);
return __nc_rref_pair_type(std::move(const_cast<key_type&>(__v.first)), std::move(__v.second));
}

_LIBCPP_HIDE_FROM_ABI __value_type& operator=(const __value_type& __v) {
__ref() = __v.__get_value();
__ref() = __get_value(__v);
return *this;
}

Expand Down Expand Up @@ -808,9 +810,17 @@ struct __value_type {
private:
value_type __cc_;

private:
static_assert(is_standard_layout_v<__hash_value_type<_Key, _Tp>>, "");

public:
_LIBCPP_HIDE_FROM_ABI value_type& __get_value() { return __cc_; }
_LIBCPP_HIDE_FROM_ABI const value_type& __get_value() const { return __cc_; }
_LIBCPP_HIDE_FROM_ABI static value_type& __get_value(__hash_value_type& __v) {
return reinterpret_cast<value_type&>(__v);
}

_LIBCPP_HIDE_FROM_ABI static const value_type& __get_value(const __hash_value_type& __v) const {
return reinterpret_cast<const value_type&>(__v);
}

__value_type() = delete;
__value_type(__value_type const&) = delete;
Expand Down Expand Up @@ -847,8 +857,10 @@ public:

_LIBCPP_HIDE_FROM_ABI __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}

_LIBCPP_HIDE_FROM_ABI reference operator*() const { return __i_->__get_value(); }
_LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__i_->__get_value()); }
_LIBCPP_HIDE_FROM_ABI reference operator*() const { return value_type::__get_value(*__i_); }
_LIBCPP_HIDE_FROM_ABI pointer operator->() const {
return pointer_traits<pointer>::pointer_to(value_type::__get_value(*__i_));
}

_LIBCPP_HIDE_FROM_ABI __map_iterator& operator++() {
++__i_;
Expand Down Expand Up @@ -905,8 +917,10 @@ public:
_LIBCPP_HIDE_FROM_ABI
__map_const_iterator(__map_iterator< typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT : __i_(__i.__i_) {}

_LIBCPP_HIDE_FROM_ABI reference operator*() const { return __i_->__get_value(); }
_LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(__i_->__get_value()); }
_LIBCPP_HIDE_FROM_ABI reference operator*() const { return value_type::__get_value(*__i_); }
_LIBCPP_HIDE_FROM_ABI pointer operator->() const {
return pointer_traits<pointer>::pointer_to(value_type::__get_value(*__i_));
}

_LIBCPP_HIDE_FROM_ABI __map_const_iterator& operator++() {
++__i_;
Expand Down Expand Up @@ -1269,7 +1283,7 @@ public:
auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, __k, std::forward<_Vp>(__v));

if (!__inserted)
__r->__get_value().second = std::forward<_Vp>(__v);
__value_type::__get_value(*__r).second = std::forward<_Vp>(__v);

return __r;
}
Expand All @@ -1280,7 +1294,7 @@ public:
__tree_.__emplace_hint_unique_key_args(__h.__i_, __k, std::move(__k), std::forward<_Vp>(__v));

if (!__inserted)
__r->__get_value().second = std::forward<_Vp>(__v);
__value_type::__get_value(*__r).second = std::forward<_Vp>(__v);

return __r;
}
Expand Down Expand Up @@ -1492,20 +1506,22 @@ map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a)

template <class _Key, class _Tp, class _Compare, class _Allocator>
_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
return __tree_
.__emplace_unique_key_args(__k, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())
.first->__get_value()
return _Tp::__get_value(__tree_
.__emplace_unique_key_args(
__k, std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())
.first)
.second;
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) {
// TODO investigate this clang-tidy warning.
// NOLINTBEGIN(bugprone-use-after-move)
return __tree_
.__emplace_unique_key_args(
__k, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())
.first->__get_value()
return _Tp::__get_value(
__tree_
.__emplace_unique_key_args(
__k, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())
.first)
.second;
// NOLINTEND(bugprone-use-after-move)
}
Expand All @@ -1517,9 +1533,9 @@ typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder
map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k) {
__node_allocator& __na = __tree_.__node_alloc();
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
__node_traits::construct(__na, std::addressof(__h->__value_.__get_value().first), __k);
__node_traits::construct(__na, std::addressof(_Tp::__get_value(__h->__value_).first), __k);
__h.get_deleter().__first_constructed = true;
__node_traits::construct(__na, std::addressof(__h->__value_.__get_value().second));
__node_traits::construct(__na, std::addressof(_Tp::__get_value(__h->__value_).second));
__h.get_deleter().__second_constructed = true;
return __h;
}
Expand All @@ -1534,7 +1550,7 @@ _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {
__tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
__r = __h.release();
}
return __r->__value_.__get_value().second;
return _Tp::__get_value(__r->__value_).second;
}

#endif // _LIBCPP_CXX03_LANG
Expand All @@ -1545,7 +1561,7 @@ _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) {
__node_base_pointer& __child = __tree_.__find_equal(__parent, __k);
if (__child == nullptr)
__throw_out_of_range("map::at: key not found");
return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
return _Tp::__get_value(static_cast<__node_pointer>(__child)->__value_).second;
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
Expand All @@ -1554,7 +1570,7 @@ const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const {
__node_base_pointer __child = __tree_.__find_equal(__parent, __k);
if (__child == nullptr)
__throw_out_of_range("map::at: key not found");
return static_cast<__node_pointer>(__child)->__value_.__get_value().second;
return _Tp::__get_value(static_cast<__node_pointer>(__child)->__value_).second;
}

template <class _Key, class _Tp, class _Compare, class _Allocator>
Expand Down
32 changes: 22 additions & 10 deletions libcxx/include/__cxx03/unordered_map
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
#include <__cxx03/__memory/addressof.h>
#include <__cxx03/__memory/allocator.h>
#include <__cxx03/__type_traits/is_allocator.h>
#include <__cxx03/__type_traits/is_standard_layout.h>
#include <__cxx03/__type_traits/type_identity.h>
#include <__cxx03/__utility/forward.h>
#include <__cxx03/stdexcept>
Expand Down Expand Up @@ -823,30 +824,33 @@ struct _LIBCPP_STANDALONE_DEBUG __hash_value_type {
private:
value_type __cc_;

private:
static_assert(std::is_standard_layout_v<__hash_value_type<_Key, _Tp>>, "");

public:
_LIBCPP_HIDE_FROM_ABI value_type& __get_value() {
_LIBCPP_HIDE_FROM_ABI static value_type& __get_value(__hash_value_type& __v) {
# if _LIBCPP_STD_VER >= 17
return *std::launder(std::addressof(__cc_));
return *std::launder(std::addressof(reinterpret_cast<const value_type&>(__v)));
# else
return __cc_;
return reinterpret_cast<const value_type&>(__v);
# endif
}

_LIBCPP_HIDE_FROM_ABI const value_type& __get_value() const {
_LIBCPP_HIDE_FROM_ABI static const value_type& __get_value(const __hash_value_type& __v) {
# if _LIBCPP_STD_VER >= 17
return *std::launder(std::addressof(__cc_));
return *std::launder(std::addressof(reinterpret_cast<value_type&>(__v)));
# else
return __cc_;
return reinterpret_cast<value_type&>(__v);
# endif
}

_LIBCPP_HIDE_FROM_ABI __nc_ref_pair_type __ref() {
value_type& __v = __get_value();
value_type& __v = __get_value(*this);
return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second);
}

_LIBCPP_HIDE_FROM_ABI __nc_rref_pair_type __move() {
value_type& __v = __get_value();
value_type& __v = __get_value(*this);
return __nc_rref_pair_type(std::move(const_cast<key_type&>(__v.first)), std::move(__v.second));
}

Expand Down Expand Up @@ -885,9 +889,17 @@ struct __hash_value_type {
private:
value_type __cc_;

private:
static_assert(is_standard_layout_v<__hash_value_type<_Key, _Tp>>, "");

public:
_LIBCPP_HIDE_FROM_ABI value_type& __get_value() { return __cc_; }
_LIBCPP_HIDE_FROM_ABI const value_type& __get_value() const { return __cc_; }
_LIBCPP_HIDE_FROM_ABI static value_type& __get_value(__hash_value_type& __v) {
return reinterpret_cast<value_type&>(__v);
}

_LIBCPP_HIDE_FROM_ABI static const value_type& __get_value(const __hash_value_type& __v) const {
return reinterpret_cast<const value_type&>(__v);
}

~__hash_value_type() = delete;
};
Expand Down
Loading