-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[libc++] Simplify a bunch of noexcept specifications #166397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
8d3f860 to
a757d96
Compare
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions ,cpp,h -- libcxx/test/libcxx/containers/sequences/vector.bool/move_noexcept.compile.pass.cpp libcxx/include/__hash_table libcxx/include/__memory/allocator_traits.h libcxx/include/__split_buffer libcxx/include/__tree libcxx/include/__vector/vector.h libcxx/include/__vector/vector_bool.h libcxx/include/deque libcxx/include/forward_list libcxx/include/list libcxx/include/queue libcxx/include/stack libcxx/include/string libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/move_noexcept.pass.cpp libcxx/test/std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move_noexcept.pass.cpp libcxx/test/std/containers/container.adaptors/flat.multiset/flat.multiset.cons/move.pass.cpp libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp libcxx/test/std/containers/sequences/deque/deque.special/swap_noexcept.pass.cpp libcxx/test/std/containers/sequences/forwardlist/forwardlist.spec/swap_noexcept.compile.pass.cpp libcxx/test/std/containers/sequences/list/list.special/swap_noexcept.pass.cpp libcxx/test/std/containers/sequences/vector.bool/swap_noexcept.pass.cpp libcxx/test/std/containers/sequences/vector/vector.cons/move_noexcept.pass.cpp libcxx/test/std/strings/basic.string/string.cons/move_noexcept.pass.cpp libcxx/test/libcxx/containers/sequences/deque/deque.cons/move_noexcept.compile.pass.cpp libcxx/test/libcxx/containers/sequences/forwardlist/move_noexcept.compile.pass.cpp libcxx/test/libcxx/containers/sequences/list/list.cons/move_noexcept.compile.pass.cpp --diff_from_common_commit
View the diff from clang-format here.diff --git a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp
index 5ffab4f0c..305736c88 100644
--- a/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/flat.set/flat.set.cons/move.pass.cpp
@@ -85,7 +85,7 @@ constexpr void test() {
template <class T>
struct PotentiallyThrowingMoveAllocator {
using value_type = T;
- explicit PotentiallyThrowingMoveAllocator() = default;
+ explicit PotentiallyThrowingMoveAllocator() = default;
PotentiallyThrowingMoveAllocator(const PotentiallyThrowingMoveAllocator&) = default;
constexpr PotentiallyThrowingMoveAllocator(PotentiallyThrowingMoveAllocator&&) noexcept(false) {}
constexpr T* allocate(std::ptrdiff_t n) { return std::allocator<T>().allocate(n); }
|
frederick-vs-ja
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other failures seem to be from aggressive assertion on non-noexcept status.
Perhaps we shouldn't write such static_assert at least in libcxx/test/std unless the function is required to throw an exception under certain conditions.
libcxx/test/libcxx/containers/sequences/forwardlist/move_noexcept.compile.pass.cpp
Show resolved
Hide resolved
libcxx/test/libcxx/containers/sequences/list/list.cons/move_noexcept.compile.pass.cpp
Show resolved
Hide resolved
7521604 to
3d12d11
Compare
3d12d11 to
3bd634d
Compare
|
@llvm/pr-subscribers-libcxx Author: Nikolas Klauser (philnik777) ChangesAllocator copy/move operations can't throw according to [allocator.requiremetns], so we can just assume that they don't instead of checking. This removes a bunch of conditional noexcept specifications and simplifies even more. Patch is 82.59 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/166397.diff 27 Files Affected:
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index e1897949a47e6..6c895ab41b7af 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -518,13 +518,13 @@ public:
_LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
: __size_(0) {}
- _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(const allocator_type& __a, size_type __size)
- _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value)
- : __size_(__size), __alloc_(__a) {}
+ _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(const allocator_type& __a, size_type __size) _NOEXCEPT
+ : __size_(__size),
+ __alloc_(__a) {}
- _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(__bucket_list_deallocator&& __x)
- _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
- : __size_(std::move(__x.__size_)), __alloc_(std::move(__x.__alloc_)) {
+ _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(__bucket_list_deallocator&& __x) _NOEXCEPT
+ : __size_(std::move(__x.__size_)),
+ __alloc_(std::move(__x.__alloc_)) {
__x.size() = 0;
}
@@ -740,16 +740,14 @@ public:
_LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a);
_LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u) _NOEXCEPT_(
is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&&
- is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<hasher>::value&&
- is_nothrow_move_constructible<key_equal>::value);
+ is_nothrow_move_constructible<hasher>::value&& is_nothrow_move_constructible<key_equal>::value);
_LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a);
_LIBCPP_HIDE_FROM_ABI ~__hash_table();
_LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u);
_LIBCPP_HIDE_FROM_ABI __hash_table& operator=(__hash_table&& __u)
_NOEXCEPT_(is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value &&
- ((__node_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<__node_allocator>::value) ||
+ (__node_traits::propagate_on_container_move_assignment::value ||
allocator_traits<__node_allocator>::is_always_equal::value));
template <class _InputIterator>
_LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last);
@@ -944,14 +942,7 @@ public:
_LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> __equal_range_multi(const _Key& __k) const;
_LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u)
-#if _LIBCPP_STD_VER <= 11
- _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal> &&
- (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
- __is_nothrow_swappable_v<__pointer_allocator>) &&
- (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>));
-#else
_NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal>);
-#endif
_LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return max_size(); }
_LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const;
@@ -1011,15 +1002,11 @@ private:
_LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type);
_LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable<hasher>::value&&
- is_nothrow_move_assignable<key_equal>::value);
- _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u) _NOEXCEPT_(
- !__node_traits::propagate_on_container_move_assignment::value ||
- (is_nothrow_move_assignable<__pointer_allocator>::value && is_nothrow_move_assignable<__node_allocator>::value)) {
+ _NOEXCEPT_(is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value);
+ _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u) _NOEXCEPT {
__move_assign_alloc(__u, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
}
- _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u, true_type) _NOEXCEPT_(
- is_nothrow_move_assignable<__pointer_allocator>::value&& is_nothrow_move_assignable<__node_allocator>::value) {
+ _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u, true_type) _NOEXCEPT {
__bucket_list_.get_deleter().__alloc() = std::move(__u.__bucket_list_.get_deleter().__alloc());
__node_alloc() = std::move(__u.__node_alloc());
}
@@ -1132,8 +1119,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u,
template <class _Tp, class _Hash, class _Equal, class _Alloc>
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) _NOEXCEPT_(
is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&&
- is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<hasher>::value&&
- is_nothrow_move_constructible<key_equal>::value)
+ is_nothrow_move_constructible<hasher>::value&& is_nothrow_move_constructible<key_equal>::value)
: __bucket_list_(std::move(__u.__bucket_list_)),
__first_node_(std::move(__u.__first_node_)),
__node_alloc_(std::move(__u.__node_alloc_)),
@@ -1278,8 +1264,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT {
template <class _Tp, class _Hash, class _Equal, class _Alloc>
void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable<hasher>::value&&
- is_nothrow_move_assignable<key_equal>::value) {
+ _NOEXCEPT_(is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value) {
clear();
__bucket_list_.reset(__u.__bucket_list_.release());
__bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size();
@@ -1325,8 +1310,7 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u,
template <class _Tp, class _Hash, class _Equal, class _Alloc>
inline __hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u)
_NOEXCEPT_(is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value &&
- ((__node_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<__node_allocator>::value) ||
+ (__node_traits::propagate_on_container_move_assignment::value ||
allocator_traits<__node_allocator>::is_always_equal::value)) {
__move_assign(__u, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
return *this;
@@ -2058,15 +2042,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(const _Key& __k) c
template <class _Tp, class _Hash, class _Equal, class _Alloc>
void __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u)
-#if _LIBCPP_STD_VER <= 11
- _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal> &&
- (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value ||
- __is_nothrow_swappable_v<__pointer_allocator>) &&
- (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>))
-#else
- _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal>)
-#endif
-{
+ _NOEXCEPT_(__is_nothrow_swappable_v<hasher>&& __is_nothrow_swappable_v<key_equal>) {
_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(
__node_traits::propagate_on_container_swap::value || this->__node_alloc() == __u.__node_alloc(),
"unordered container::swap: Either propagate_on_container_swap "
diff --git a/libcxx/include/__memory/noexcept_move_assign_container.h b/libcxx/include/__memory/noexcept_move_assign_container.h
index b0063516aaafc..e752d46496227 100644
--- a/libcxx/include/__memory/noexcept_move_assign_container.h
+++ b/libcxx/include/__memory/noexcept_move_assign_container.h
@@ -12,7 +12,6 @@
#include <__config>
#include <__memory/allocator_traits.h>
#include <__type_traits/integral_constant.h>
-#include <__type_traits/is_nothrow_assignable.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -26,8 +25,6 @@ struct __noexcept_move_assign_container
_Traits::propagate_on_container_move_assignment::value
#if _LIBCPP_STD_VER >= 17
|| _Traits::is_always_equal::value
-#else
- && is_nothrow_move_assignable<_Alloc>::value
#endif
> {
};
diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer
index 1e05e4df8ba0f..e25a4cc997577 100644
--- a/libcxx/include/__split_buffer
+++ b/libcxx/include/__split_buffer
@@ -28,8 +28,6 @@
#include <__type_traits/conditional.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/integral_constant.h>
-#include <__type_traits/is_nothrow_assignable.h>
-#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/is_swappable.h>
#include <__type_traits/is_trivially_destructible.h>
#include <__type_traits/is_trivially_relocatable.h>
@@ -184,8 +182,7 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
- __copy_without_alloc(__split_buffer_pointer_layout const& __other)
- _NOEXCEPT_(is_nothrow_copy_assignable<pointer>::value) {
+ __copy_without_alloc(__split_buffer_pointer_layout const& __other) _NOEXCEPT {
__front_cap_ = __other.__front_cap_;
__begin_ = __other.__begin_;
__end_ = __other.__end_;
@@ -341,8 +338,7 @@ public:
}
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
- __copy_without_alloc(__split_buffer_size_layout const& __other)
- _NOEXCEPT_(is_nothrow_copy_assignable<pointer>::value) {
+ __copy_without_alloc(__split_buffer_size_layout const& __other) _NOEXCEPT {
__front_cap_ = __other.__front_cap_;
__begin_ = __other.__begin_;
__cap_ = __other.__cap_;
@@ -497,15 +493,11 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c)
- _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c) _NOEXCEPT;
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c)
- _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value) ||
- !__alloc_traits::propagate_on_container_move_assignment::value);
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c) _NOEXCEPT;
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer();
@@ -559,8 +551,7 @@ public:
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__alloc_rr>);
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x) _NOEXCEPT;
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const {
if (__front_cap() == nullptr) {
@@ -594,8 +585,8 @@ public:
}
private:
- _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer& __c, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
+ __move_assign_alloc(__split_buffer& __c, true_type) _NOEXCEPT {
__get_allocator() = std::move(__c.__get_allocator());
}
@@ -740,8 +731,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>::~__split
}
template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>::__split_buffer(__split_buffer&& __c)
- _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
+_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>::__split_buffer(__split_buffer&& __c) _NOEXCEPT
: __base_type(std::move(__c)) {
__c.__reset();
}
@@ -767,10 +757,7 @@ __split_buffer<_Tp, _Allocator, _Layout>::__split_buffer(__split_buffer&& __c, c
template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator, _Layout>&
-__split_buffer<_Tp, _Allocator, _Layout>::operator=(__split_buffer&& __c)
- _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<allocator_type>::value) ||
- !__alloc_traits::propagate_on_container_move_assignment::value) {
+__split_buffer<_Tp, _Allocator, _Layout>::operator=(__split_buffer&& __c) _NOEXCEPT {
clear();
shrink_to_fit();
__copy_without_alloc(__c);
@@ -780,8 +767,7 @@ __split_buffer<_Tp, _Allocator, _Layout>::operator=(__split_buffer&& __c)
}
template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
-_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::swap(__split_buffer& __x)
- _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__alloc_rr>) {
+_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::swap(__split_buffer& __x) _NOEXCEPT {
__base_type::swap(__x);
}
@@ -852,8 +838,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator, _Layout>::emp
template <class _Tp, class _Allocator, template <class, class, class> class _Layout>
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
-swap(__split_buffer<_Tp, _Allocator, _Layout>& __x, __split_buffer<_Tp, _Allocator, _Layout>& __y)
- _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
+swap(__split_buffer<_Tp, _Allocator, _Layout>& __x, __split_buffer<_Tp, _Allocator, _Layout>& __y) _NOEXCEPT {
__x.swap(__y);
}
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index ceae22bb48702..fedb31187d89b 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -904,14 +904,12 @@ public:
_LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last);
template <class _InputIterator>
_LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last);
- _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_(
- is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value);
+ _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) _NOEXCEPT_(is_nothrow_move_constructible<value_compare>::value);
_LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a);
_LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t)
_NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value &&
- ((__node_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<__node_allocator>::value) ||
+ (__node_traits::propagate_on_container_move_assignment::value ||
allocator_traits<__node_allocator>::is_always_equal::value)) {
__move_assign(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
return *this;
@@ -933,13 +931,7 @@ public:
_LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT;
- _LIBCPP_HIDE_FROM_ABI void swap(__tree& __t)
-#if _LIBCPP_STD_VER <= 11
- _NOEXCEPT_(__is_nothrow_swappable_v<value_compare> &&
- (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>));
-#else
- _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>);
-#endif
+ _LIBCPP_HIDE_FROM_ABI void swap(__tree& __t) _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>);
template <class... _Args>
_LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args);
@@ -1281,17 +1273,14 @@ private:
_LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT { (__tree_deleter(__node_alloc_))(__nd); }
_LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, false_type);
- _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, true_type) _NOEXCEPT_(
- is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value);
+ _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, true_type)
+ _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value);
- _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t)
- _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
- is_nothrow_move_assignable<__node_allocator>::value) {
+ _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t) _NOEXCEPT {
__move_assign_alloc(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>());
}
- _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {
+ _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree& __t, true_type) _NOEXCEPT {
__node_alloc() = std::move(__t.__node_alloc());
}
_LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
@@ -1605,8 +1594,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t)
}
template <class _Tp, class _Compare, class _Allocator>
-__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(
- is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible<value_compare>::value)
+__tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) _NOEXCEPT_(is_nothrow_move_constructible<value_compare>::value)
: __begin_node_(std::move(__t.__begin_node_)),
__end_node_(std::move(__t.__end_node_)),
__node_alloc_(std::move(__t.__node_alloc_)),
@@ -1649,7 +1637,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __
template <class _Tp, class _Compare, class _Allocator>
void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type)
- _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value&& is_nothrow_move_assignable<__node_allocator>::value) {
+ _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value) {
destroy(static_cast<__node_pointer>(__end_node()->__left_));
__begin_node_ = __t.__begin_node_;
__end_node_ = __t.__end_node_;
@@ -1687,14 +1675,7 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
}
template <class _Tp, class _Compare, class _Allocator>
-void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t)
-#if _LIBCPP_STD_VER <= 11
- _NOEXCEPT_(__is_nothrow_swappable_v<value_compare> &&
- (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>))
-#else
- _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>)
-#endif
-{
+void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) _NOEXCEPT_(__is_nothrow_swappable_v<value_compare>) {
using std::swap;
swap(__begin_node_, __t.__begin_node_);
swap(__end_node_, __t.__end_node_);
diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h
ind...
[truncated]
|
ldionne
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can only guess, but I suspect the reason for having written these conditional noexcepts this way could be the fact that Clang generates sub-optimal code when calling a non-noexcept function from a noexcept function. It basically generates a try-catch that calls terminate in the catch block.
Hence, it's technically possible that we'd start generating worse code when we have an allocator that doesn't throw but fails to be marked as noexcept. Arguably, we should fix Clang's strategy for handling this as discussed in https://discourse.llvm.org/t/rfc-add-call-unwindabort-to-llvm-ir.
Generally speaking LGTM but I'd like you to investigate the situation for move-assignment operators.
3bd634d to
11fccc6
Compare
| is_nothrow_move_assignable<__node_allocator>::value) || | ||
| allocator_traits<__node_allocator>::is_always_equal::value)); | ||
| _NOEXCEPT_(is_nothrow_move_assignable<hasher>::value&& is_nothrow_move_assignable<key_equal>::value&& | ||
| __is_allocator_aware_container_move_nothrow_v<allocator_type>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a libc++ specific test for these properties that we were apparently not testing previously.
Or if we're already testing this somehow, there should be a test changing in std::unordered_map and friends.
Allocator copy/move operations can't throw according to [allocator.requirements], so we can just assume that they don't instead of checking. This removes a bunch of conditional noexcept specifications and simplifies even more.