diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -2728,9 +2728,9 @@ __u.__bucket_list_.reset(__npp); } _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); - __swap_allocator(__bucket_list_.get_deleter().__alloc(), + _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(), __u.__bucket_list_.get_deleter().__alloc()); - __swap_allocator(__node_alloc(), __u.__node_alloc()); + _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc()); _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); __p2_.swap(__u.__p2_); __p3_.swap(__u.__p3_); diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer --- a/libcxx/include/__split_buffer +++ b/libcxx/include/__split_buffer @@ -279,7 +279,7 @@ __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) { while (__begin_ != __new_begin) - __alloc_traits::destroy(__alloc(), __to_address(__begin_++)); + __alloc_traits::destroy(__alloc(), _VSTD::__to_address(__begin_++)); } template @@ -296,7 +296,7 @@ __split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT { while (__new_last != __end_) - __alloc_traits::destroy(__alloc(), __to_address(--__end_)); + __alloc_traits::destroy(__alloc(), _VSTD::__to_address(--__end_)); } template @@ -416,7 +416,7 @@ _VSTD::swap(__begin_, __x.__begin_); _VSTD::swap(__end_, __x.__end_); _VSTD::swap(__end_cap(), __x.__end_cap()); - __swap_allocator(__alloc(), __x.__alloc()); + _VSTD::__swap_allocator(__alloc(), __x.__alloc()); } template diff --git a/libcxx/include/__tree b/libcxx/include/__tree --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -1819,7 +1819,7 @@ using _VSTD::swap; swap(__begin_node_, __t.__begin_node_); swap(__pair1_.first(), __t.__pair1_.first()); - __swap_allocator(__node_alloc(), __t.__node_alloc()); + _VSTD::__swap_allocator(__node_alloc(), __t.__node_alloc()); __pair3_.swap(__t.__pair3_); if (size() == 0) __begin_node() = __end_node(); diff --git a/libcxx/include/deque b/libcxx/include/deque --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -1237,7 +1237,7 @@ __map_.swap(__c.__map_); _VSTD::swap(__start_, __c.__start_); _VSTD::swap(size(), __c.size()); - __swap_allocator(__alloc(), __c.__alloc()); + _VSTD::__swap_allocator(__alloc(), __c.__alloc()); } template @@ -2376,7 +2376,7 @@ for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) { _ConstructTransaction __tx(this, __br); for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { - __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f); + __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), *__f); } } } @@ -2393,7 +2393,7 @@ for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) { _ConstructTransaction __tx(this, __br); for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { - __alloc_traits::construct(__a, std::__to_address(__tx.__pos_)); + __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_)); } } } @@ -2410,7 +2410,7 @@ for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) { _ConstructTransaction __tx(this, __br); for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { - __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v); + __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), __v); } } @@ -2708,7 +2708,7 @@ deque<_Tp, _Allocator>::pop_front() { allocator_type& __a = __base::__alloc(); - __alloc_traits::destroy(__a, __to_address(*(__base::__map_.begin() + + __alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() + __base::__start_ / __base::__block_size) + __base::__start_ % __base::__block_size)); --__base::size(); @@ -2723,7 +2723,7 @@ _LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque"); allocator_type& __a = __base::__alloc(); size_type __p = __base::size() + __base::__start_ - 1; - __alloc_traits::destroy(__a, __to_address(*(__base::__map_.begin() + + __alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size)); --__base::size(); diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -603,7 +603,7 @@ __is_nothrow_swappable<__node_allocator>::value) #endif { - __swap_allocator(__alloc(), __x.__alloc(), + _VSTD::__swap_allocator(__alloc(), __x.__alloc(), integral_constant()); using _VSTD::swap; swap(__before_begin()->__next_, __x.__before_begin()->__next_); diff --git a/libcxx/include/list b/libcxx/include/list --- a/libcxx/include/list +++ b/libcxx/include/list @@ -783,7 +783,7 @@ "list::swap: Either propagate_on_container_swap must be true" " or the allocators must compare equal"); using _VSTD::swap; - __swap_allocator(__node_alloc(), __c.__node_alloc()); + _VSTD::__swap_allocator(__node_alloc(), __c.__node_alloc()); swap(__sz(), __c.__sz()); swap(__end_, __c.__end_); if (__sz() == 0) diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -4890,35 +4890,35 @@ // --- Helper for container swap -- template -inline _LIBCPP_INLINE_VISIBILITY -void __swap_allocator(_Alloc & __a1, _Alloc & __a2) +_LIBCPP_INLINE_VISIBILITY +void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) #endif { - __swap_allocator(__a1, __a2, - integral_constant::propagate_on_container_swap::value>()); + using _VSTD::swap; + swap(__a1, __a2); } template -_LIBCPP_INLINE_VISIBILITY -void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) +inline _LIBCPP_INLINE_VISIBILITY +void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __swap_allocator(_Alloc & __a1, _Alloc & __a2) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) #endif { - using _VSTD::swap; - swap(__a1, __a2); + _VSTD::__swap_allocator(__a1, __a2, + integral_constant::propagate_on_container_swap::value>()); } -template -inline _LIBCPP_INLINE_VISIBILITY -void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} - template > struct __noexcept_move_assign_container : public integral_constant__alloc(), this->__begin_, this->__end_, __v.__begin_); + _VSTD::__construct_backward_with_exception_guarantees(this->__alloc(), this->__begin_, this->__end_, __v.__begin_); _VSTD::swap(this->__begin_, __v.__begin_); _VSTD::swap(this->__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); @@ -966,8 +966,8 @@ { __annotate_delete(); pointer __r = __v.__begin_; - __construct_backward_with_exception_guarantees(this->__alloc(), this->__begin_, __p, __v.__begin_); - __construct_forward_with_exception_guarantees(this->__alloc(), __p, this->__end_, __v.__end_); + _VSTD::__construct_backward_with_exception_guarantees(this->__alloc(), this->__begin_, __p, __v.__begin_); + _VSTD::__construct_forward_with_exception_guarantees(this->__alloc(), __p, this->__end_, __v.__end_); _VSTD::swap(this->__begin_, __v.__begin_); _VSTD::swap(this->__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); @@ -1074,7 +1074,7 @@ vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n) { _ConstructTransaction __tx(*this, __n); - __construct_range_forward(this->__alloc(), __first, __last, __tx.__pos_); + _VSTD::__construct_range_forward(this->__alloc(), __first, __last, __tx.__pos_); } // Default constructs __n objects starting at __end_ @@ -2054,7 +2054,7 @@ _VSTD::swap(this->__begin_, __x.__begin_); _VSTD::swap(this->__end_, __x.__end_); _VSTD::swap(this->__end_cap(), __x.__end_cap()); - __swap_allocator(this->__alloc(), __x.__alloc(), + _VSTD::__swap_allocator(this->__alloc(), __x.__alloc(), integral_constant()); #if _LIBCPP_DEBUG_LEVEL == 2 __get_db()->swap(this, &__x); @@ -3232,7 +3232,7 @@ _VSTD::swap(this->__begin_, __x.__begin_); _VSTD::swap(this->__size_, __x.__size_); _VSTD::swap(this->__cap(), __x.__cap()); - __swap_allocator(this->__alloc(), __x.__alloc(), + _VSTD::__swap_allocator(this->__alloc(), __x.__alloc(), integral_constant()); } diff --git a/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +#include + +#include "test_macros.h" + +struct Incomplete; +template struct Holder { T t; }; + +template> +struct MyAlloc { + using value_type = T; + T *allocate(int n) { return std::allocator().allocate(n); } + void deallocate(T *p, int n) { return std::allocator().deallocate(p, n); } +}; + +int main(int, char**) +{ + std::vector> v; + std::vector> w; + v.push_back(1); + v.insert(v.end(), 2); + v.insert(v.end(), w.begin(), w.end()); + v.pop_back(); + v.erase(v.begin()); + v.erase(v.begin(), v.end()); +#if TEST_STD_VER >= 14 + v.swap(w); +#endif + return 0; +}