diff options
Diffstat (limited to 'include/unordered_map')
-rw-r--r-- | include/unordered_map | 112 |
1 files changed, 81 insertions, 31 deletions
diff --git a/include/unordered_map b/include/unordered_map index 725cb6af2759..f34d82efdc33 100644 --- a/include/unordered_map +++ b/include/unordered_map @@ -396,7 +396,7 @@ public: const _Hash& hash_function() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Cp& __x) const - {return static_cast<const _Hash&>(*this)(__x.__cc.first);} + {return static_cast<const _Hash&>(*this)(__x.__get_value().first);} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Key& __x) const {return static_cast<const _Hash&>(*this)(__x);} @@ -425,7 +425,7 @@ public: const _Hash& hash_function() const _NOEXCEPT {return __hash_;} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Cp& __x) const - {return __hash_(__x.__cc.first);} + {return __hash_(__x.__get_value().first);} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Key& __x) const {return __hash_(__x);} @@ -464,13 +464,13 @@ public: const _Pred& key_eq() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Cp& __y) const - {return static_cast<const _Pred&>(*this)(__x.__cc.first, __y.__cc.first);} + {return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y.__get_value().first);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Key& __y) const - {return static_cast<const _Pred&>(*this)(__x.__cc.first, __y);} + {return static_cast<const _Pred&>(*this)(__x.__get_value().first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _Cp& __y) const - {return static_cast<const _Pred&>(*this)(__x, __y.__cc.first);} + {return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);} void swap(__unordered_map_equal&__y) _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) { @@ -496,13 +496,13 @@ public: const _Pred& key_eq() const _NOEXCEPT {return __pred_;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Cp& __y) const - {return __pred_(__x.__cc.first, __y.__cc.first);} + {return __pred_(__x.__get_value().first, __y.__get_value().first);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Key& __y) const - {return __pred_(__x.__cc.first, __y);} + {return __pred_(__x.__get_value().first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _Cp& __y) const - {return __pred_(__x, __y.__cc.first);} + {return __pred_(__x, __y.__get_value().first);} void swap(__unordered_map_equal&__y) _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) { @@ -572,9 +572,9 @@ public: void operator()(pointer __p) _NOEXCEPT { if (__second_constructed) - __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.second)); + __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().second)); if (__first_constructed) - __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__cc.first)); + __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().first)); if (__p) __alloc_traits::deallocate(__na_, __p, 1); } @@ -582,23 +582,67 @@ public: #ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp> -union __hash_value_type +struct __hash_value_type { typedef _Key key_type; typedef _Tp mapped_type; typedef pair<const key_type, mapped_type> value_type; - typedef pair<key_type, mapped_type> __nc_value_type; + typedef pair<key_type&, mapped_type&> __nc_ref_pair_type; + typedef pair<key_type&&, mapped_type&&> __nc_rref_pair_type; +private: value_type __cc; - __nc_value_type __nc; + +public: + _LIBCPP_INLINE_VISIBILITY + value_type& __get_value() + { +#if _LIBCPP_STD_VER > 14 + return *_VSTD::launder(_VSTD::addressof(__cc)); +#else + return __cc; +#endif + } + + _LIBCPP_INLINE_VISIBILITY + const value_type& __get_value() const + { +#if _LIBCPP_STD_VER > 14 + return *_VSTD::launder(_VSTD::addressof(__cc)); +#else + return __cc; +#endif + } + + _LIBCPP_INLINE_VISIBILITY + __nc_ref_pair_type __ref() + { + value_type& __v = __get_value(); + return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second); + } + + _LIBCPP_INLINE_VISIBILITY + __nc_rref_pair_type __move() + { + value_type& __v = __get_value(); + return __nc_rref_pair_type( + _VSTD::move(const_cast<key_type&>(__v.first)), + _VSTD::move(__v.second)); + } _LIBCPP_INLINE_VISIBILITY __hash_value_type& operator=(const __hash_value_type& __v) - {__nc = __v.__cc; return *this;} + { + __ref() = __v.__get_value(); + return *this; + } _LIBCPP_INLINE_VISIBILITY __hash_value_type& operator=(__hash_value_type&& __v) - {__nc = _VSTD::move(__v.__nc); return *this;} + { + __ref() = __v.__move(); + return *this; + } template <class _ValueTp, class = typename enable_if< @@ -606,8 +650,10 @@ union __hash_value_type >::type > _LIBCPP_INLINE_VISIBILITY - __hash_value_type& operator=(_ValueTp&& __v) { - __nc = _VSTD::forward<_ValueTp>(__v); return *this; + __hash_value_type& operator=(_ValueTp&& __v) + { + __ref() = _VSTD::forward<_ValueTp>(__v); + return *this; } private: @@ -628,8 +674,15 @@ struct __hash_value_type typedef _Tp mapped_type; typedef pair<const key_type, mapped_type> value_type; +private: value_type __cc; +public: + _LIBCPP_INLINE_VISIBILITY + value_type& __get_value() { return __cc; } + _LIBCPP_INLINE_VISIBILITY + const value_type& __get_value() const { return __cc; } + private: ~__hash_value_type(); }; @@ -657,9 +710,9 @@ public: __hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {} _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __i_->__cc;} + reference operator*() const {return __i_->__get_value();} _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);} + pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());} _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;} @@ -711,9 +764,9 @@ public: : __i_(__i.__i_) {} _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __i_->__cc;} + reference operator*() const {return __i_->__get_value();} _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__cc);} + pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());} _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator& operator++() {++__i_; return *this;} @@ -750,7 +803,6 @@ public: typedef _Pred key_equal; typedef _Alloc allocator_type; typedef pair<const key_type, mapped_type> value_type; - typedef pair<key_type, mapped_type> __nc_value_type; typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), @@ -1298,8 +1350,8 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( { iterator __i = __u.begin(); while (__u.size() != 0) { - __table_.__emplace_unique(_VSTD::move( - __u.__table_.remove((__i++).__i_)->__value_.__nc)); + __table_.__emplace_unique( + __u.__table_.remove((__i++).__i_)->__value_.__move()); } } #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1385,7 +1437,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) { return __table_.__emplace_unique_key_args(__k, std::piecewise_construct, std::forward_as_tuple(__k), - std::forward_as_tuple()).first->__cc.second; + std::forward_as_tuple()).first->__get_value().second; } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -1394,7 +1446,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k) { return __table_.__emplace_unique_key_args(__k, std::piecewise_construct, std::forward_as_tuple(std::move(__k)), - std::forward_as_tuple()).first->__cc.second; + std::forward_as_tuple()).first->__get_value().second; } #else // _LIBCPP_CXX03_LANG @@ -1404,9 +1456,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const { __node_allocator& __na = __table_.__node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), __k); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().first), __k); __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); + __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().second)); __h.get_deleter().__second_constructed = true; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } @@ -1500,7 +1552,6 @@ public: typedef _Pred key_equal; typedef _Alloc allocator_type; typedef pair<const key_type, mapped_type> value_type; - typedef pair<key_type, mapped_type> __nc_value_type; typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), @@ -1915,8 +1966,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( while (__u.size() != 0) { __table_.__insert_multi( - _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_.__nc) - ); + __u.__table_.remove((__i++).__i_)->__value_.__move()); } } #if _LIBCPP_DEBUG_LEVEL >= 2 |