[libcxx-commits] [libcxx] [libc++] Move allocator assertion into allocator_traits (PR #94750)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jun 9 12:00:45 PDT 2024
https://github.com/huixie90 updated https://github.com/llvm/llvm-project/pull/94750
>From e886812ee99e25c8ad571459deab1b3ca5d85e7a Mon Sep 17 00:00:00 2001
From: Hui <hui.xie0621 at gmail.com>
Date: Fri, 7 Jun 2024 20:02:07 +0100
Subject: [PATCH] [libc++] reuse allocator validitity check logic and message
---
libcxx/include/__memory/allocator_traits.h | 8 ++++++++
libcxx/include/deque | 5 ++---
libcxx/include/forward_list | 6 ++----
libcxx/include/list | 4 +---
libcxx/include/map | 8 ++------
libcxx/include/set | 8 ++------
libcxx/include/string | 4 +---
libcxx/include/unordered_map | 8 ++------
libcxx/include/unordered_set | 4 +---
libcxx/include/vector | 4 +---
10 files changed, 22 insertions(+), 37 deletions(-)
diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index 47fe132d15cb1..ccc200922c1b1 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -372,6 +372,14 @@ template <class _Traits, class _Tp>
using __rebind_alloc = typename _Traits::template rebind_alloc<_Tp>::other;
#endif
+template <class _Alloc>
+struct __check_valid_allocator : std::true_type {
+ using _Traits = std::allocator_traits<_Alloc>;
+ static_assert(is_same<_Alloc, __rebind_alloc<_Traits, typename _Traits::value_type> >::value,
+ "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
+ "original allocator");
+};
+
// __is_default_allocator
template <class _Tp>
struct __is_default_allocator : false_type {};
diff --git a/libcxx/include/deque b/libcxx/include/deque
index 555761aae6afd..94edcf02ae96a 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -477,9 +477,8 @@ public:
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
- static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
+
static_assert(is_nothrow_default_constructible<allocator_type>::value ==
is_nothrow_default_constructible<__pointer_allocator>::value,
"rebinding an allocator should not change excpetion guarantees");
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 363931e3f2388..8806cf3d00ffa 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -650,13 +650,11 @@ public:
typedef _Tp value_type;
typedef _Alloc allocator_type;
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
+
static_assert(is_same<value_type, typename allocator_type::value_type>::value,
"Allocator::value_type must be same type as value_type");
- static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
-
static_assert((!is_same<allocator_type, __node_allocator>::value),
"internal allocator type must differ from user-specified "
"type; otherwise overload resolution breaks");
diff --git a/libcxx/include/list b/libcxx/include/list
index 87f15e144ac8f..0ced9af230379 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -692,9 +692,7 @@ public:
typedef void __remove_return_type;
#endif
- static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value);
_LIBCPP_HIDE_FROM_ABI list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {}
_LIBCPP_HIDE_FROM_ABI explicit list(const allocator_type& __a) : base(__a) {}
diff --git a/libcxx/include/map b/libcxx/include/map
index 7efa715e84aa7..fd3bc791ba681 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -999,9 +999,7 @@ private:
typedef typename __base::__node_traits __node_traits;
typedef allocator_traits<allocator_type> __alloc_traits;
- static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
__base __tree_;
@@ -1684,9 +1682,7 @@ private:
typedef typename __base::__node_traits __node_traits;
typedef allocator_traits<allocator_type> __alloc_traits;
- static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
__base __tree_;
diff --git a/libcxx/include/set b/libcxx/include/set
index ab3a4363499af..83d6e47eb11b4 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -578,9 +578,7 @@ private:
typedef __tree<value_type, value_compare, allocator_type> __base;
typedef allocator_traits<allocator_type> __alloc_traits;
- static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
__base __tree_;
@@ -1035,9 +1033,7 @@ private:
typedef __tree<value_type, value_compare, allocator_type> __base;
typedef allocator_traits<allocator_type> __alloc_traits;
- static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
__base __tree_;
diff --git a/libcxx/include/string b/libcxx/include/string
index 1db803e822d72..870eea06dca3e 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -782,9 +782,7 @@ public:
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
- static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
// TODO: Implement iterator bounds checking without requiring the global database.
typedef __wrap_iter<pointer> iterator;
diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map
index 2e25b0f050695..7c2c51bc06231 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -1059,9 +1059,7 @@ private:
typedef unique_ptr<__node, _Dp> __node_holder;
typedef allocator_traits<allocator_type> __alloc_traits;
- static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
static_assert((is_same<typename __table::__container_value_type, value_type>::value), "");
static_assert((is_same<typename __table::__node_value_type, __value_type>::value), "");
@@ -1866,9 +1864,7 @@ private:
static_assert((is_same<typename __node_traits::size_type, typename __alloc_traits::size_type>::value),
"Allocator uses different size_type for different types");
- static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
public:
typedef typename __alloc_traits::pointer pointer;
diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index c966cc8eb4df1..1f73d1541d02f 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -591,9 +591,7 @@ public:
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
"Allocator::value_type must be same type as value_type");
- static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
private:
typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
diff --git a/libcxx/include/vector b/libcxx/include/vector
index cbfc2cefa1fd9..1a02cb9602cde 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -409,9 +409,7 @@ public:
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
- static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
- "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
- "original allocator");
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) {}
More information about the libcxx-commits
mailing list