Author: epilk Date: Mon Jun 4 13:38:23 2018 New Revision: 333948 URL: http://llvm.org/viewvc/llvm-project?rev=333948&view=rev Log: Fix a strict aliasing violation in map and unordered_map.
These containers type-punned between pair<K, V> and pair<const K, V> as an optimization. This commit instead provides access to the pair via a pair of references that assign through to the underlying object. It's still undefined to mutate a const object, but clang doesn't optimize on this for data members, so this should be safe. Differential revision: https://reviews.llvm.org/D47607 Modified: libcxx/trunk/include/__hash_table libcxx/trunk/include/__tree libcxx/trunk/include/map libcxx/trunk/include/unordered_map Modified: libcxx/trunk/include/__hash_table URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__hash_table?rev=333948&r1=333947&r2=333948&view=diff ============================================================================== --- libcxx/trunk/include/__hash_table (original) +++ libcxx/trunk/include/__hash_table Mon Jun 4 13:38:23 2018 @@ -32,13 +32,8 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -#ifndef _LIBCPP_CXX03_LANG -template <class _Key, class _Tp> -union __hash_value_type; -#else template <class _Key, class _Tp> struct __hash_value_type; -#endif template <class _Key, class _Cp, class _Hash, bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value> @@ -172,7 +167,7 @@ struct __hash_key_value_types { } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY - static __container_value_type&& __move(__node_value_type& __v) { + static __container_value_type&& __move(__node_value_type& __v) { return _VSTD::move(__v); } #endif @@ -184,7 +179,6 @@ struct __hash_key_value_types<__hash_val typedef _Tp mapped_type; typedef __hash_value_type<_Key, _Tp> __node_value_type; typedef pair<const _Key, _Tp> __container_value_type; - typedef pair<_Key, _Tp> __nc_value_type; typedef __container_value_type __map_value_type; static const bool __is_map = true; @@ -198,7 +192,7 @@ struct __hash_key_value_types<__hash_val static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&>::type __get_value(_Up& __t) { - return __t.__cc; + return __t.__get_value(); } template <class _Up> @@ -211,12 +205,12 @@ struct __hash_key_value_types<__hash_val _LIBCPP_INLINE_VISIBILITY static __container_value_type* __get_ptr(__node_value_type& __n) { - return _VSTD::addressof(__n.__cc); + return _VSTD::addressof(__n.__get_value()); } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY - static __nc_value_type&& __move(__node_value_type& __v) { - return _VSTD::move(__v.__nc); + static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { + return __v.__move(); } #endif Modified: libcxx/trunk/include/__tree URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__tree?rev=333948&r1=333947&r2=333948&view=diff ============================================================================== --- libcxx/trunk/include/__tree (original) +++ libcxx/trunk/include/__tree Mon Jun 4 13:38:23 2018 @@ -37,13 +37,8 @@ template <class _Pointer> class __tree_e template <class _VoidPtr> class __tree_node_base; template <class _Tp, class _VoidPtr> class __tree_node; -#ifndef _LIBCPP_CXX03_LANG -template <class _Key, class _Value> -union __value_type; -#else template <class _Key, class _Value> struct __value_type; -#endif template <class _Key, class _CP, class _Compare, bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value> @@ -569,10 +564,9 @@ struct __tree_key_value_types { static __container_value_type* __get_ptr(__node_value_type& __n) { return _VSTD::addressof(__n); } - #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY - static __container_value_type&& __move(__node_value_type& __v) { + static __container_value_type&& __move(__node_value_type& __v) { return _VSTD::move(__v); } #endif @@ -584,14 +578,13 @@ struct __tree_key_value_types<__value_ty typedef _Tp mapped_type; typedef __value_type<_Key, _Tp> __node_value_type; typedef pair<const _Key, _Tp> __container_value_type; - typedef pair<_Key, _Tp> __nc_value_type; typedef __container_value_type __map_value_type; static const bool __is_map = true; _LIBCPP_INLINE_VISIBILITY static key_type const& __get_key(__node_value_type const& __t) { - return __t.__cc.first; + return __t.__get_value().first; } template <class _Up> @@ -605,7 +598,7 @@ struct __tree_key_value_types<__value_ty _LIBCPP_INLINE_VISIBILITY static __container_value_type const& __get_value(__node_value_type const& __t) { - return __t.__cc; + return __t.__get_value(); } template <class _Up> @@ -618,13 +611,13 @@ struct __tree_key_value_types<__value_ty _LIBCPP_INLINE_VISIBILITY static __container_value_type* __get_ptr(__node_value_type& __n) { - return _VSTD::addressof(__n.__cc); + return _VSTD::addressof(__n.__get_value()); } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY - static __nc_value_type&& __move(__node_value_type& __v) { - return _VSTD::move(__v.__nc); + static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { + return __v.__move(); } #endif }; Modified: libcxx/trunk/include/map URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/map?rev=333948&r1=333947&r2=333948&view=diff ============================================================================== --- libcxx/trunk/include/map (original) +++ libcxx/trunk/include/map Mon Jun 4 13:38:23 2018 @@ -470,13 +470,13 @@ public: const _Compare& key_comp() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _CP& __x, const _CP& __y) const - {return static_cast<const _Compare&>(*this)(__x.__cc.first, __y.__cc.first);} + {return static_cast<const _Compare&>(*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 _Compare&>(*this)(__x.__cc.first, __y);} + {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _CP& __y) const - {return static_cast<const _Compare&>(*this)(__x, __y.__cc.first);} + {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);} void swap(__map_value_compare&__y) _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) { @@ -489,13 +489,13 @@ public: _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () ( const _K2& __x, const _CP& __y ) const - {return static_cast<const _Compare&>(*this) (__x, __y.__cc.first);} + {return static_cast<const _Compare&>(*this) (__x, __y.__get_value().first);} template <typename _K2> _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () (const _CP& __x, const _K2& __y) const - {return static_cast<const _Compare&>(*this) (__x.__cc.first, __y);} + {return static_cast<const _Compare&>(*this) (__x.__get_value().first, __y);} #endif }; @@ -518,13 +518,13 @@ public: _LIBCPP_INLINE_VISIBILITY bool operator()(const _CP& __x, const _CP& __y) const - {return comp(__x.__cc.first, __y.__cc.first);} + {return comp(__x.__get_value().first, __y.__get_value().first);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _CP& __x, const _Key& __y) const - {return comp(__x.__cc.first, __y);} + {return comp(__x.__get_value().first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _CP& __y) const - {return comp(__x, __y.__cc.first);} + {return comp(__x, __y.__get_value().first);} void swap(__map_value_compare&__y) _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) { @@ -537,13 +537,13 @@ public: _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () ( const _K2& __x, const _CP& __y ) const - {return comp (__x, __y.__cc.first);} + {return comp (__x, __y.__get_value().first);} template <typename _K2> _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () (const _CP& __x, const _K2& __y) const - {return comp (__x.__cc.first, __y);} + {return comp (__x.__get_value().first, __y);} #endif }; @@ -597,9 +597,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); } @@ -614,23 +614,67 @@ template <class _TreeIterator> class __m #ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp> -union __value_type +struct __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 __value_type& operator=(const __value_type& __v) - {__nc = __v.__cc; return *this;} + { + __ref() = __v.__get_value(); + return *this; + } _LIBCPP_INLINE_VISIBILITY __value_type& operator=(__value_type&& __v) - {__nc = _VSTD::move(__v.__nc); return *this;} + { + __ref() = __v.__move(); + return *this; + } template <class _ValueTp, class = typename enable_if< @@ -638,8 +682,10 @@ union __value_type >::type > _LIBCPP_INLINE_VISIBILITY - __value_type& operator=(_ValueTp&& __v) { - __nc = _VSTD::forward<_ValueTp>(__v); return *this; + __value_type& operator=(_ValueTp&& __v) + { + __ref() = _VSTD::forward<_ValueTp>(__v); + return *this; } private: @@ -658,8 +704,15 @@ struct __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: __value_type(); __value_type(__value_type const&); @@ -701,9 +754,9 @@ public: __map_iterator(_TreeIterator __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 __map_iterator& operator++() {++__i_; return *this;} @@ -764,9 +817,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 __map_const_iterator& operator++() {++__i_; return *this;} @@ -809,7 +862,6 @@ public: 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 _Compare key_compare; typedef _Allocator allocator_type; typedef value_type& reference; @@ -1308,7 +1360,7 @@ map<_Key, _Tp, _Compare, _Allocator>::ma const_iterator __e = cend(); while (!__m.empty()) __tree_.__insert_unique(__e.__i_, - _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc)); + __m.__tree_.remove(__m.begin().__i_)->__value_.__move()); } } @@ -1319,7 +1371,7 @@ map<_Key, _Tp, _Compare, _Allocator>::op return __tree_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), - _VSTD::forward_as_tuple()).first->__cc.second; + _VSTD::forward_as_tuple()).first->__get_value().second; } template <class _Key, class _Tp, class _Compare, class _Allocator> @@ -1329,7 +1381,7 @@ map<_Key, _Tp, _Compare, _Allocator>::op return __tree_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), - _VSTD::forward_as_tuple()).first->__cc.second; + _VSTD::forward_as_tuple()).first->__get_value().second; } #else // _LIBCPP_CXX03_LANG @@ -1340,9 +1392,9 @@ map<_Key, _Tp, _Compare, _Allocator>::__ { __node_allocator& __na = __tree_.__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 } @@ -1360,7 +1412,7 @@ map<_Key, _Tp, _Compare, _Allocator>::op __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); __r = __h.release(); } - return __r->__value_.__cc.second; + return __r->__value_.__get_value().second; } #endif // _LIBCPP_CXX03_LANG @@ -1375,7 +1427,7 @@ map<_Key, _Tp, _Compare, _Allocator>::at if (__child == nullptr) throw out_of_range("map::at: key not found"); #endif // _LIBCPP_NO_EXCEPTIONS - return static_cast<__node_pointer>(__child)->__value_.__cc.second; + return static_cast<__node_pointer>(__child)->__value_.__get_value().second; } template <class _Key, class _Tp, class _Compare, class _Allocator> @@ -1388,7 +1440,7 @@ map<_Key, _Tp, _Compare, _Allocator>::at if (__child == nullptr) throw out_of_range("map::at: key not found"); #endif // _LIBCPP_NO_EXCEPTIONS - return static_cast<__node_pointer>(__child)->__value_.__cc.second; + return static_cast<__node_pointer>(__child)->__value_.__get_value().second; } @@ -1465,7 +1517,6 @@ public: 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 _Compare key_compare; typedef _Allocator allocator_type; typedef value_type& reference; @@ -1852,7 +1903,7 @@ multimap<_Key, _Tp, _Compare, _Allocator const_iterator __e = cend(); while (!__m.empty()) __tree_.__insert_multi(__e.__i_, - _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc)); + _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__move())); } } #endif Modified: libcxx/trunk/include/unordered_map URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/unordered_map?rev=333948&r1=333947&r2=333948&view=diff ============================================================================== --- libcxx/trunk/include/unordered_map (original) +++ libcxx/trunk/include/unordered_map Mon Jun 4 13:38:23 2018 @@ -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, _ { 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, _ { 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, _ { 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, _ { __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, _Pr 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits