diff --git a/libcxx/include/__memory/compressed_pair.h b/libcxx/include/__memory/compressed_pair.h --- a/libcxx/include/__memory/compressed_pair.h +++ b/libcxx/include/__memory/compressed_pair.h @@ -161,6 +161,14 @@ __x.swap(__y); } +template +struct __compressed_pair_padding {}; + +template +struct __compressed_pair_padding<_Type, __enable_if_t<__libcpp_is_final<_Type>::value && is_empty<_Type>::value> > { + char __padding_; +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___MEMORY_COMPRESSED_PAIR_H diff --git a/libcxx/include/string b/libcxx/include/string --- a/libcxx/include/string +++ b/libcxx/include/string @@ -750,17 +750,14 @@ size_type __words[__n_words]; }; - struct __rep + union { - union - { - __long __l; - __short __s; - __raw __r; - }; + __long __l; + __short __s; + __raw __r; }; - - __compressed_pair<__rep, allocator_type> __r_; + _LIBCPP_NO_UNIQUE_ADDRESS __compressed_pair_padding __padding; + _LIBCPP_NO_UNIQUE_ADDRESS allocator_type __alloc; public: _LIBCPP_TEMPLATE_DATA_VIS @@ -794,9 +791,9 @@ template ::value, nullptr_t> > _LIBCPP_INLINE_VISIBILITY - basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) { - _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); - __init(__s, traits_type::length(__s)); + basic_string(const _CharT* __str) { + _LIBCPP_ASSERT(__str != nullptr, "basic_string(const char*) detected nullptr"); + __init(__str, traits_type::length(__str)); _VSTD::__debug_db_insert_c(this); } @@ -870,7 +867,7 @@ _LIBCPP_INLINE_VISIBILITY basic_string& operator=(initializer_list __il) {return assign(__il.begin(), __il.size());} #endif - _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __s) {return assign(__s);} + _LIBCPP_INLINE_VISIBILITY basic_string& operator=(const value_type* __str) {return assign(__str);} #if _LIBCPP_STD_VER > 20 basic_string& operator=(nullptr_t) = delete; #endif @@ -1023,7 +1020,7 @@ > _LIBCPP_INLINE_VISIBILITY append(_InputIterator __first, _InputIterator __last) { - const basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc); append(__temp.data(), __temp.size()); return *this; } @@ -1234,7 +1231,7 @@ #endif _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT {return __alloc();} + allocator_type get_allocator() const _NOEXCEPT {return __alloc;} _LIBCPP_INLINE_VISIBILITY size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; @@ -1383,8 +1380,8 @@ { return !empty() && _Traits::eq(front(), __c); } constexpr _LIBCPP_INLINE_VISIBILITY - bool starts_with(const value_type* __s) const noexcept - { return starts_with(__self_view(__s)); } + bool starts_with(const value_type* __str) const noexcept + { return starts_with(__self_view(__str)); } constexpr _LIBCPP_INLINE_VISIBILITY bool ends_with(__self_view __sv) const noexcept @@ -1395,8 +1392,8 @@ { return !empty() && _Traits::eq(back(), __c); } constexpr _LIBCPP_INLINE_VISIBILITY - bool ends_with(const value_type* __s) const noexcept - { return ends_with(__self_view(__s)); } + bool ends_with(const value_type* __str) const noexcept + { return ends_with(__self_view(__str)); } #endif #if _LIBCPP_STD_VER > 20 @@ -1409,8 +1406,8 @@ { return __self_view(data(), size()).contains(__c); } constexpr _LIBCPP_INLINE_VISIBILITY - bool contains(const value_type* __s) const - { return __self_view(data(), size()).contains(__s); } + bool contains(const value_type* __str) const + { return __self_view(data(), size()).contains(__str); } #endif _LIBCPP_INLINE_VISIBILITY bool __invariants() const; @@ -1421,7 +1418,7 @@ _LIBCPP_INLINE_VISIBILITY bool __is_long() const _NOEXCEPT - {return bool(__r_.first().__s.__size_ & __short_mask);} + {return bool(__s.__size_ & __short_mask);} #if _LIBCPP_DEBUG_LEVEL == 2 @@ -1465,79 +1462,76 @@ return begin() + __ip; } - _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __r_.second(); } - _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); } - #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT _LIBCPP_INLINE_VISIBILITY void __set_short_size(size_type __s) _NOEXCEPT # ifdef _LIBCPP_BIG_ENDIAN - {__r_.first().__s.__size_ = (unsigned char)(__s << 1);} + {__s.__size_ = (unsigned char)(__s << 1);} # else - {__r_.first().__s.__size_ = (unsigned char)(__s);} + {__s.__size_ = (unsigned char)(__s);} # endif _LIBCPP_INLINE_VISIBILITY size_type __get_short_size() const _NOEXCEPT # ifdef _LIBCPP_BIG_ENDIAN - {return __r_.first().__s.__size_ >> 1;} + {__s.__size_ >> 1;} # else - {return __r_.first().__s.__size_;} + {__s.__size_;} # endif #else // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT _LIBCPP_INLINE_VISIBILITY - void __set_short_size(size_type __s) _NOEXCEPT + void __set_short_size(size_type __sz) _NOEXCEPT # ifdef _LIBCPP_BIG_ENDIAN - {__r_.first().__s.__size_ = (unsigned char)(__s);} + {__s.__size_ = (unsigned char)(__s);} # else - {__r_.first().__s.__size_ = (unsigned char)(__s << 1);} + {__s.__size_ = (unsigned char)(__sz << 1);} # endif _LIBCPP_INLINE_VISIBILITY size_type __get_short_size() const _NOEXCEPT # ifdef _LIBCPP_BIG_ENDIAN - {return __r_.first().__s.__size_;} + {return __s.__size_;} # else - {return __r_.first().__s.__size_ >> 1;} + {return __s.__size_ >> 1;} # endif #endif // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT _LIBCPP_INLINE_VISIBILITY - void __set_long_size(size_type __s) _NOEXCEPT - {__r_.first().__l.__size_ = __s;} + void __set_long_size(size_type __sz) _NOEXCEPT + {__l.__size_ = __sz;} _LIBCPP_INLINE_VISIBILITY size_type __get_long_size() const _NOEXCEPT - {return __r_.first().__l.__size_;} + {return __l.__size_;} _LIBCPP_INLINE_VISIBILITY - void __set_size(size_type __s) _NOEXCEPT - {if (__is_long()) __set_long_size(__s); else __set_short_size(__s);} + void __set_size(size_type __sz) _NOEXCEPT + {if (__is_long()) __set_long_size(__sz); else __set_short_size(__sz);} _LIBCPP_INLINE_VISIBILITY - void __set_long_cap(size_type __s) _NOEXCEPT - {__r_.first().__l.__cap_ = __long_mask | __s;} + void __set_long_cap(size_type __sz) _NOEXCEPT + {__l.__cap_ = __long_mask | __sz;} _LIBCPP_INLINE_VISIBILITY size_type __get_long_cap() const _NOEXCEPT - {return __r_.first().__l.__cap_ & size_type(~__long_mask);} + {return __l.__cap_ & size_type(~__long_mask);} _LIBCPP_INLINE_VISIBILITY void __set_long_pointer(pointer __p) _NOEXCEPT - {__r_.first().__l.__data_ = __p;} + {__l.__data_ = __p;} _LIBCPP_INLINE_VISIBILITY pointer __get_long_pointer() _NOEXCEPT - {return __r_.first().__l.__data_;} + {return __l.__data_;} _LIBCPP_INLINE_VISIBILITY const_pointer __get_long_pointer() const _NOEXCEPT - {return __r_.first().__l.__data_;} + {return __l.__data_;} _LIBCPP_INLINE_VISIBILITY pointer __get_short_pointer() _NOEXCEPT - {return pointer_traits::pointer_to(__r_.first().__s.__data_[0]);} + {return pointer_traits::pointer_to(__s.__data_[0]);} _LIBCPP_INLINE_VISIBILITY const_pointer __get_short_pointer() const _NOEXCEPT - {return pointer_traits::pointer_to(__r_.first().__s.__data_[0]);} + {return pointer_traits::pointer_to(__s.__data_[0]);} _LIBCPP_INLINE_VISIBILITY pointer __get_pointer() _NOEXCEPT {return __is_long() ? __get_long_pointer() : __get_short_pointer();} @@ -1548,7 +1542,7 @@ _LIBCPP_INLINE_VISIBILITY void __zero() _NOEXCEPT { - size_type (&__a)[__n_words] = __r_.first().__r.__words; + size_type (&__a)[__n_words] = __r.__words; for (unsigned __i = 0; __i < __n_words; ++__i) __a[__i] = 0; } @@ -1628,21 +1622,21 @@ _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const basic_string& __str, true_type) { - if (__alloc() == __str.__alloc()) - __alloc() = __str.__alloc(); + if (__alloc == __str.__alloc) + __alloc = __str.__alloc; else { if (!__str.__is_long()) { __clear_and_shrink(); - __alloc() = __str.__alloc(); + __alloc = __str.__alloc; } else { - allocator_type __a = __str.__alloc(); + allocator_type __a = __str.__alloc; pointer __p = __alloc_traits::allocate(__a, __str.__get_long_cap()); __clear_and_shrink(); - __alloc() = _VSTD::move(__a); + __alloc = _VSTD::move(__a); __set_long_pointer(__p); __set_long_cap(__str.__get_long_cap()); __set_long_size(__str.size()); @@ -1680,7 +1674,7 @@ void __move_assign_alloc(basic_string& __c, true_type) _NOEXCEPT_(is_nothrow_move_assignable::value) { - __alloc() = _VSTD::move(__c.__alloc()); + __alloc = _VSTD::move(__c.__alloc); } _LIBCPP_INLINE_VISIBILITY @@ -1823,7 +1817,6 @@ inline basic_string<_CharT, _Traits, _Allocator>::basic_string() _NOEXCEPT_(is_nothrow_default_constructible::value) - : __r_(__default_init_tag(), __default_init_tag()) { _VSTD::__debug_db_insert_c(this); __zero(); @@ -1837,14 +1830,14 @@ #else _NOEXCEPT #endif -: __r_(__default_init_tag(), __a) +: __alloc(__a) { _VSTD::__debug_db_insert_c(this); __zero(); } template -void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, +void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __str, size_type __sz, size_type __reserve) { @@ -1859,18 +1852,18 @@ else { size_type __cap = __recommend(__reserve); - __p = __alloc_traits::allocate(__alloc(), __cap+1); + __p = __alloc_traits::allocate(__alloc, __cap+1); __set_long_pointer(__p); __set_long_cap(__cap+1); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz); + traits_type::copy(_VSTD::__to_address(__p), __str, __sz); traits_type::assign(__p[__sz], value_type()); } template void -basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz) +basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __str, size_type __sz) { if (__sz > max_size()) __throw_length_error(); @@ -1883,51 +1876,50 @@ else { size_type __cap = __recommend(__sz); - __p = __alloc_traits::allocate(__alloc(), __cap+1); + __p = __alloc_traits::allocate(__alloc, __cap+1); __set_long_pointer(__p); __set_long_cap(__cap+1); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz); + traits_type::copy(_VSTD::__to_address(__p), __str, __sz); traits_type::assign(__p[__sz], value_type()); } template template -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) - : __r_(__default_init_tag(), __a) +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __str, const _Allocator& __a) + : __alloc(__a) { - _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); - __init(__s, traits_type::length(__s)); + _LIBCPP_ASSERT(__str != nullptr, "basic_string(const char*, allocator) detected nullptr"); + __init(__str, traits_type::length(__str)); _VSTD::__debug_db_insert_c(this); } template inline -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) - : __r_(__default_init_tag(), __default_init_tag()) +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __str, size_type __n) { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); - __init(__s, __n); + _LIBCPP_ASSERT(__n == 0 || __str != nullptr, "basic_string(const char*, n) detected nullptr"); + __init(__str, __n); _VSTD::__debug_db_insert_c(this); } template inline -basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) - : __r_(__default_init_tag(), __a) +basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __str, size_type __n, const _Allocator& __a) + : __alloc(__a) { - _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); - __init(__s, __n); + _LIBCPP_ASSERT(__n == 0 || __str != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); + __init(__str, __n); _VSTD::__debug_db_insert_c(this); } template basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) - : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) + : __alloc(__alloc_traits::select_on_container_copy_construction(__str.__alloc)) { if (!__str.__is_long()) - __r_.first().__r = __str.__r_.first().__r; + __r = __str.__r; else __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); @@ -1937,10 +1929,10 @@ template basic_string<_CharT, _Traits, _Allocator>::basic_string( const basic_string& __str, const allocator_type& __a) - : __r_(__default_init_tag(), __a) + : __alloc(__a) { if (!__str.__is_long()) - __r_.first().__r = __str.__r_.first().__r; + __r = __str.__r; else __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); @@ -1949,7 +1941,7 @@ template void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( - const value_type* __s, size_type __sz) { + const value_type* __str, size_type __sz) { pointer __p; if (__fits_in_sso(__sz)) { __p = __get_short_pointer(); @@ -1958,12 +1950,12 @@ if (__sz > max_size()) __throw_length_error(); size_t __cap = __recommend(__sz); - __p = __alloc_traits::allocate(__alloc(), __cap + 1); + __p = __alloc_traits::allocate(__alloc, __cap + 1); __set_long_pointer(__p); __set_long_cap(__cap + 1); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_address(__p), __s, __sz + 1); + traits_type::copy(_VSTD::__to_address(__p), __str, __sz + 1); } #ifndef _LIBCPP_CXX03_LANG @@ -1976,7 +1968,7 @@ #else _NOEXCEPT #endif - : __r_(_VSTD::move(__str.__r_)) + : __r(__str.__r), __alloc(std::move(__str.__alloc)) { __str.__zero(); _VSTD::__debug_db_insert_c(this); @@ -1989,13 +1981,13 @@ template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) - : __r_(__default_init_tag(), __a) + : __alloc(__a) { - if (__str.__is_long() && __a != __str.__alloc()) // copy, not move + if (__str.__is_long() && __a != __str.__alloc) // copy, not move __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); else { - __r_.first().__r = __str.__r_.first().__r; + __r = __str.__r; __str.__zero(); } _VSTD::__debug_db_insert_c(this); @@ -2022,7 +2014,7 @@ else { size_type __cap = __recommend(__n); - __p = __alloc_traits::allocate(__alloc(), __cap+1); + __p = __alloc_traits::allocate(__alloc, __cap+1); __set_long_pointer(__p); __set_long_cap(__cap+1); __set_long_size(__n); @@ -2034,7 +2026,6 @@ template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) - : __r_(__default_init_tag(), __default_init_tag()) { __init(__n, __c); _VSTD::__debug_db_insert_c(this); @@ -2043,7 +2034,7 @@ template template basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) - : __r_(__default_init_tag(), __a) + : __alloc(__a) { __init(__n, __c); _VSTD::__debug_db_insert_c(this); @@ -2053,7 +2044,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a) - : __r_(__default_init_tag(), __a) + : __alloc(__a) { size_type __str_sz = __str.size(); if (__pos > __str_sz) @@ -2066,7 +2057,7 @@ inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a) - : __r_(__default_init_tag(), __a) + : __alloc(__a) { size_type __str_sz = __str.size(); if (__pos > __str_sz) @@ -2079,7 +2070,7 @@ template basic_string<_CharT, _Traits, _Allocator>::basic_string( const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) - : __r_(__default_init_tag(), __a) + : __alloc(__a) { __self_view __sv0 = __t; __self_view __sv = __sv0.substr(__pos, __n); @@ -2090,7 +2081,6 @@ template template basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) - : __r_(__default_init_tag(), __default_init_tag()) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); @@ -2100,7 +2090,7 @@ template template basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) - : __r_(__default_init_tag(), __a) + : __alloc(__a) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); @@ -2127,7 +2117,7 @@ catch (...) { if (__is_long()) - __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); + __alloc_traits::deallocate(__alloc, __get_long_pointer(), __get_long_cap()); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2153,7 +2143,7 @@ else { size_type __cap = __recommend(__sz); - __p = __alloc_traits::allocate(__alloc(), __cap+1); + __p = __alloc_traits::allocate(__alloc, __cap+1); __set_long_pointer(__p); __set_long_cap(__cap+1); __set_long_size(__sz); @@ -2171,7 +2161,7 @@ catch (...) { if (__is_long()) - __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); + __alloc_traits::deallocate(__alloc, __get_long_pointer(), __get_long_cap()); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2181,7 +2171,6 @@ template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) - : __r_(__default_init_tag(), __default_init_tag()) { __init(__first, __last); _VSTD::__debug_db_insert_c(this); @@ -2192,7 +2181,7 @@ inline basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a) - : __r_(__default_init_tag(), __a) + : __alloc(__a) { __init(__first, __last); _VSTD::__debug_db_insert_c(this); @@ -2202,9 +2191,7 @@ template inline -basic_string<_CharT, _Traits, _Allocator>::basic_string( - initializer_list<_CharT> __il) - : __r_(__default_init_tag(), __default_init_tag()) +basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<_CharT> __il) { __init(__il.begin(), __il.end()); _VSTD::__debug_db_insert_c(this); @@ -2215,7 +2202,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il, const _Allocator& __a) - : __r_(__default_init_tag(), __a) + : __alloc(__a) { __init(__il.begin(), __il.end()); _VSTD::__debug_db_insert_c(this); @@ -2231,7 +2218,7 @@ __get_db()->__erase_c(this); #endif if (__is_long()) - __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); + __alloc_traits::deallocate(__alloc, __get_long_pointer(), __get_long_cap()); } template @@ -2247,7 +2234,7 @@ size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; - pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); + pointer __p = __alloc_traits::allocate(__alloc, __cap+1); __invalidate_all_iterators(); if (__n_copy != 0) traits_type::copy(_VSTD::__to_address(__p), @@ -2259,7 +2246,7 @@ traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); if (__old_cap+1 != __min_cap) - __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); + __alloc_traits::deallocate(__alloc, __old_p, __old_cap+1); __set_long_pointer(__p); __set_long_cap(__cap+1); __old_sz = __n_copy + __n_add + __sec_cp_sz; @@ -2279,7 +2266,7 @@ size_type __cap = __old_cap < __ms / 2 - __alignment ? __recommend(_VSTD::max(__old_cap + __delta_cap, 2 * __old_cap)) : __ms - 1; - pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); + pointer __p = __alloc_traits::allocate(__alloc, __cap+1); __invalidate_all_iterators(); if (__n_copy != 0) traits_type::copy(_VSTD::__to_address(__p), @@ -2290,7 +2277,7 @@ _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); if (__old_cap+1 != __min_cap) - __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); + __alloc_traits::deallocate(__alloc, __old_p, __old_cap+1); __set_long_pointer(__p); __set_long_cap(__cap+1); } @@ -2386,7 +2373,7 @@ __copy_assign_alloc(__str); if (!__is_long()) { if (!__str.__is_long()) { - __r_.first().__r = __str.__r_.first().__r; + __r = __str.__r; } else { return __assign_no_alias(__str.data(), __str.size()); } @@ -2405,7 +2392,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) _NOEXCEPT_(__alloc_traits::is_always_equal::value) { - if (__alloc() != __str.__alloc()) + if (__alloc != __str.__alloc) assign(__str); else __move_assign(__str, true_type()); @@ -2422,7 +2409,7 @@ #endif { if (__is_long()) { - __alloc_traits::deallocate(__alloc(), __get_long_pointer(), + __alloc_traits::deallocate(__alloc, __get_long_pointer(), __get_long_cap()); #if _LIBCPP_STD_VER <= 14 if (!is_nothrow_move_assignable::value) { @@ -2432,7 +2419,7 @@ #endif } __move_assign_alloc(__str); - __r_.first() = __str.__r_.first(); + __r = __str.__r; __str.__set_short_size(0); traits_type::assign(__str.__get_short_pointer()[0], value_type()); } @@ -2459,7 +2446,7 @@ > basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) { - const basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc); assign(__temp.data(), __temp.size()); return *this; } @@ -2494,7 +2481,7 @@ } else { - const basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc); assign(__temp.data(), __temp.size()); } return *this; @@ -2671,7 +2658,7 @@ } else { - const basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc); append(__temp.data(), __temp.size()); } } @@ -2797,7 +2784,7 @@ _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, "string::insert(iterator, range) called with an iterator not" " referring to this string"); - const basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc); return insert(__pos, __temp.data(), __temp.data() + __temp.size()); } @@ -2824,7 +2811,7 @@ } else { - const basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc); return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end()); } } @@ -3006,7 +2993,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) { - const basic_string __temp(__j1, __j2, __alloc()); + const basic_string __temp(__j1, __j2, __alloc); return replace(__i1, __i2, __temp); } @@ -3216,7 +3203,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT { - size_type __m = __alloc_traits::max_size(__alloc()); + size_type __m = __alloc_traits::max_size(__alloc); #ifdef _LIBCPP_BIG_ENDIAN return (__m <= ~__long_mask ? __m : __m/2) - __alignment; #else @@ -3275,14 +3262,14 @@ else { if (__target_capacity > __cap) - __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1); + __new_data = __alloc_traits::allocate(__alloc, __target_capacity+1); else { #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - __new_data = __alloc_traits::allocate(__alloc(), __target_capacity+1); + __new_data = __alloc_traits::allocate(__alloc, __target_capacity+1); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -3301,7 +3288,7 @@ traits_type::copy(_VSTD::__to_address(__new_data), _VSTD::__to_address(__p), size()+1); if (__was_long) - __alloc_traits::deallocate(__alloc(), __p, __cap+1); + __alloc_traits::deallocate(__alloc, __p, __cap+1); if (__now_long) { __set_long_cap(__target_capacity+1); @@ -3402,7 +3389,7 @@ basic_string<_CharT, _Traits, _Allocator> basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const { - return basic_string(*this, __pos, __n, __alloc()); + return basic_string(*this, __pos, __n, __alloc); } template @@ -3428,9 +3415,9 @@ _LIBCPP_ASSERT( __alloc_traits::propagate_on_container_swap::value || __alloc_traits::is_always_equal::value || - __alloc() == __str.__alloc(), "swapping non-equal allocators"); - _VSTD::swap(__r_.first(), __str.__r_.first()); - _VSTD::__swap_allocator(__alloc(), __str.__alloc()); + __alloc == __str.__alloc, "swapping non-equal allocators"); + _VSTD::swap(__r, __str.__r); + _VSTD::__swap_allocator(__alloc, __str.__alloc); } // find @@ -3948,7 +3935,7 @@ clear(); if(__is_long()) { - __alloc_traits::deallocate(__alloc(), __get_long_pointer(), capacity() + 1); + __alloc_traits::deallocate(__alloc, __get_long_pointer(), capacity() + 1); __set_long_cap(0); __set_short_size(0); traits_type::assign(*__get_short_pointer(), value_type()); diff --git a/libcxx/test/libcxx/no_unique_address_keep_abi.compile.pass.cpp b/libcxx/test/libcxx/no_unique_address_keep_abi.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/no_unique_address_keep_abi.compile.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// XFAIL: c++03 + +#include +#include + +#include "test_allocator.h" +#include "test_macros.h" + +struct Empty1 {}; +struct Empty2 {}; + +struct FinalEmpty1 final {}; +struct FinalEmpty2 final {}; + +struct NotEmpty1 { char c[22]; }; +struct NotEmpty2 { char c[10]; }; + +struct FinalNotEmpty1 final { char c[22]; }; +struct FinalNotEmpty2 final { char c[10]; }; + +struct FitsInPadding { int i; char c; }; + +template +struct new_compressed_pair { + _LIBCPP_NO_UNIQUE_ADDRESS std::__compressed_pair_padding __padding1; + _LIBCPP_NO_UNIQUE_ADDRESS T __element1; + _LIBCPP_NO_UNIQUE_ADDRESS std::__compressed_pair_padding __padding2; + _LIBCPP_NO_UNIQUE_ADDRESS U __element2; +}; + +template ::value && !std::__libcpp_is_final<_Tp>::value> +struct compressed_pair_elem { _Tp __value_; }; + +template +struct compressed_pair_elem<_Tp, _Idx, true> : private _Tp {}; + +template +class compressed_pair : private compressed_pair_elem<_T1, 0>, + private compressed_pair_elem<_T2, 1> {}; + +static_assert(sizeof(new_compressed_pair) == sizeof(compressed_pair), ""); +static_assert(sizeof(new_compressed_pair) == sizeof(compressed_pair), ""); +static_assert(sizeof(new_compressed_pair) == sizeof(compressed_pair), ""); +static_assert(sizeof(new_compressed_pair) == sizeof(compressed_pair), ""); +static_assert(sizeof(new_compressed_pair) == sizeof(compressed_pair), ""); +static_assert(sizeof(new_compressed_pair) == sizeof(compressed_pair), ""); +static_assert(sizeof(new_compressed_pair) == sizeof(compressed_pair), ""); +static_assert(sizeof(new_compressed_pair) == sizeof(compressed_pair), ""); +static_assert(sizeof(new_compressed_pair) == sizeof(compressed_pair)); + +static_assert(sizeof(std::string) == 2 * sizeof(size_t) + sizeof(compressed_pair>), ""); +#ifndef TEST_HAS_NO_CHAR8_T +static_assert(sizeof(std::u8string) == 2 * sizeof(size_t) + sizeof(compressed_pair>), ""); +#endif +static_assert(sizeof(std::u16string) == 2 * sizeof(size_t) + sizeof(compressed_pair>), ""); +static_assert(sizeof(std::u32string) == 2 * sizeof(size_t) + sizeof(compressed_pair>), ""); + +namespace N1 { +template +using alloc_string = std::basic_string, test_allocator>; + +static_assert(sizeof(alloc_string) == 2 * sizeof(unsigned) + sizeof(compressed_pair>), ""); +#ifndef TEST_HAS_NO_CHAR8_T +static_assert(sizeof(alloc_string) == 2 * sizeof(unsigned) + sizeof(compressed_pair>), ""); +#endif +static_assert(sizeof(alloc_string) == 2 * sizeof(unsigned) + sizeof(compressed_pair>), ""); +static_assert(sizeof(alloc_string) == 2 * sizeof(unsigned) + sizeof(compressed_pair>), ""); +} // namespace N1 + +namespace N2 { +template +using alloc_string = std::basic_string, non_default_test_allocator>; + +static_assert(sizeof(alloc_string) == 2 * sizeof(unsigned) + sizeof(compressed_pair>), ""); +#ifndef TEST_HAS_NO_CHAR8_T +static_assert(sizeof(alloc_string) == 2 * sizeof(unsigned) + sizeof(compressed_pair>), ""); +#endif +static_assert(sizeof(alloc_string) == 2 * sizeof(unsigned) + sizeof(compressed_pair>), ""); +static_assert(sizeof(alloc_string) == 2 * sizeof(unsigned) + sizeof(compressed_pair>), ""); +} // namespace N2