Index: libcxx/include/__hash_table =================================================================== --- libcxx/include/__hash_table +++ libcxx/include/__hash_table @@ -32,13 +32,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#ifndef _LIBCPP_CXX03_LANG -template -union __hash_value_type; -#else template struct __hash_value_type; -#endif template ::value && !__libcpp_is_final<_Hash>::value> @@ -172,7 +167,7 @@ } #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 @@ typedef _Tp mapped_type; typedef __hash_value_type<_Key, _Tp> __node_value_type; typedef pair __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 @@ 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 @@ -211,12 +205,12 @@ _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 __move(__node_value_type& __v) { + return __v.__move(); } #endif Index: libcxx/include/__tree =================================================================== --- libcxx/include/__tree +++ libcxx/include/__tree @@ -37,13 +37,8 @@ template class __tree_node_base; template class __tree_node; -#ifndef _LIBCPP_CXX03_LANG -template -union __value_type; -#else template struct __value_type; -#endif template ::value && !__libcpp_is_final<_Compare>::value> @@ -569,10 +564,9 @@ 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 @@ typedef _Tp mapped_type; typedef __value_type<_Key, _Tp> __node_value_type; typedef pair __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 @@ -605,7 +598,7 @@ _LIBCPP_INLINE_VISIBILITY static __container_value_type const& __get_value(__node_value_type const& __t) { - return __t.__cc; + return __t.__get_value(); } template @@ -618,13 +611,13 @@ _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 __move(__node_value_type& __v) { + return __v.__move(); } #endif }; Index: libcxx/include/map =================================================================== --- libcxx/include/map +++ libcxx/include/map @@ -470,13 +470,13 @@ const _Compare& key_comp() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _CP& __x, const _CP& __y) const - {return static_cast(*this)(__x.__cc.first, __y.__cc.first);} + {return static_cast(*this)(__x.__get_value().first, __y.__get_value().first);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _CP& __x, const _Key& __y) const - {return static_cast(*this)(__x.__cc.first, __y);} + {return static_cast(*this)(__x.__get_value().first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _CP& __y) const - {return static_cast(*this)(__x, __y.__cc.first);} + {return static_cast(*this)(__x, __y.__get_value().first);} void swap(__map_value_compare&__y) _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) { @@ -489,13 +489,13 @@ _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () ( const _K2& __x, const _CP& __y ) const - {return static_cast(*this) (__x, __y.__cc.first);} + {return static_cast(*this) (__x, __y.__get_value().first);} template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type operator () (const _CP& __x, const _K2& __y) const - {return static_cast(*this) (__x.__cc.first, __y);} + {return static_cast(*this) (__x.__get_value().first, __y);} #endif }; @@ -518,13 +518,13 @@ _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 @@ _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 _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 @@ 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 @@ #ifndef _LIBCPP_CXX03_LANG template -union __value_type +struct __value_type { typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; - typedef pair __nc_value_type; + typedef pair __nc_ref_pair_type; + typedef pair __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(__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(__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 ::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 @@ typedef _Tp mapped_type; typedef pair 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 @@ __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_to(__i_->__cc);} + pointer operator->() const {return pointer_traits::pointer_to(__i_->__get_value());} _LIBCPP_INLINE_VISIBILITY __map_iterator& operator++() {++__i_; return *this;} @@ -764,9 +817,9 @@ : __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_to(__i_->__cc);} + pointer operator->() const {return pointer_traits::pointer_to(__i_->__get_value());} _LIBCPP_INLINE_VISIBILITY __map_const_iterator& operator++() {++__i_; return *this;} @@ -809,7 +862,6 @@ typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; - typedef pair __nc_value_type; typedef _Compare key_compare; typedef _Allocator allocator_type; typedef value_type& reference; @@ -1308,7 +1360,7 @@ 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 @@ 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 @@ -1329,7 +1381,7 @@ 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 @@ { __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 @@ __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 @@ 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 @@ -1388,7 +1440,7 @@ 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 @@ typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; - typedef pair __nc_value_type; typedef _Compare key_compare; typedef _Allocator allocator_type; typedef value_type& reference; @@ -1852,7 +1903,7 @@ 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 Index: libcxx/include/unordered_map =================================================================== --- libcxx/include/unordered_map +++ libcxx/include/unordered_map @@ -396,7 +396,7 @@ const _Hash& hash_function() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Cp& __x) const - {return static_cast(*this)(__x.__cc.first);} + {return static_cast(*this)(__x.__get_value().first);} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Key& __x) const {return static_cast(*this)(__x);} @@ -425,7 +425,7 @@ 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 @@ const _Pred& key_eq() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Cp& __y) const - {return static_cast(*this)(__x.__cc.first, __y.__cc.first);} + {return static_cast(*this)(__x.__get_value().first, __y.__get_value().first);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Cp& __x, const _Key& __y) const - {return static_cast(*this)(__x.__cc.first, __y);} + {return static_cast(*this)(__x.__get_value().first, __y);} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Key& __x, const _Cp& __y) const - {return static_cast(*this)(__x, __y.__cc.first);} + {return static_cast(*this)(__x, __y.__get_value().first);} void swap(__unordered_map_equal&__y) _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) { @@ -496,13 +496,13 @@ 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 @@ 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 @@ #ifndef _LIBCPP_CXX03_LANG template -union __hash_value_type +struct __hash_value_type { typedef _Key key_type; typedef _Tp mapped_type; typedef pair value_type; - typedef pair __nc_value_type; + typedef pair __nc_ref_pair_type; + typedef pair __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(__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(__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 ::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 @@ typedef _Tp mapped_type; typedef pair 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 @@ __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_to(__i_->__cc);} + pointer operator->() const {return pointer_traits::pointer_to(__i_->__get_value());} _LIBCPP_INLINE_VISIBILITY __hash_map_iterator& operator++() {++__i_; return *this;} @@ -711,9 +764,9 @@ : __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_to(__i_->__cc);} + pointer operator->() const {return pointer_traits::pointer_to(__i_->__get_value());} _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator& operator++() {++__i_; return *this;} @@ -750,7 +803,6 @@ typedef _Pred key_equal; typedef _Alloc allocator_type; typedef pair value_type; - typedef pair __nc_value_type; typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same::value), @@ -1298,8 +1350,8 @@ { 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 @@ { 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 @@ -1394,7 +1446,7 @@ { 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 @@ { __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 @@ typedef _Pred key_equal; typedef _Alloc allocator_type; typedef pair value_type; - typedef pair __nc_value_type; typedef value_type& reference; typedef const value_type& const_reference; static_assert((is_same::value), @@ -1915,8 +1966,7 @@ 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