[libcxx-commits] [libcxx] 79e8a59 - [libc++] Move allocator assertion into allocator_traits (#94750)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jun 25 08:13:52 PDT 2024
Author: Hui
Date: 2024-06-25T10:13:48-05:00
New Revision: 79e8a5952366eacd92201a8d6472726fc14e00fd
URL: https://github.com/llvm/llvm-project/commit/79e8a5952366eacd92201a8d6472726fc14e00fd
DIFF: https://github.com/llvm/llvm-project/commit/79e8a5952366eacd92201a8d6472726fc14e00fd.diff
LOG: [libc++] Move allocator assertion into allocator_traits (#94750)
There is code duplication in all containers that static_assert the
allocator matches the allocator requirements in the spec. This check can
be moved into a more centralised place.
Added:
Modified:
libcxx/include/__memory/allocator_traits.h
libcxx/include/deque
libcxx/include/forward_list
libcxx/include/list
libcxx/include/map
libcxx/include/set
libcxx/include/string
libcxx/include/unordered_map
libcxx/include/unordered_set
libcxx/include/vector
Removed:
################################################################################
diff --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index 47fe132d15cb1..ac564f0e6fa0c 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -16,6 +16,7 @@
#include <__type_traits/enable_if.h>
#include <__type_traits/is_constructible.h>
#include <__type_traits/is_empty.h>
+#include <__type_traits/is_same.h>
#include <__type_traits/make_unsigned.h>
#include <__type_traits/remove_reference.h>
#include <__type_traits/void_t.h>
@@ -372,6 +373,14 @@ template <class _Traits, class _Tp>
using __rebind_alloc = typename _Traits::template rebind_alloc<_Tp>::other;
#endif
+template <class _Alloc>
+struct __check_valid_allocator : 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 43ed8c46866ec..aee4764859dd2 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -449,11 +449,11 @@ public:
using value_type = _Tp;
- static_assert(is_same<typename _Allocator::value_type, value_type>::value,
- "Allocator::value_type must be same type as value_type");
-
using allocator_type = _Allocator;
using __alloc_traits = allocator_traits<allocator_type>;
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
+ static_assert(is_same<typename allocator_type::value_type, value_type>::value,
+ "Allocator::value_type must be same type as value_type");
using size_type = typename __alloc_traits::size_type;
using
diff erence_type = typename __alloc_traits::
diff erence_type;
@@ -488,9 +488,6 @@ public:
deque,
void>;
- 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(is_nothrow_default_constructible<allocator_type>::value ==
is_nothrow_default_constructible<__pointer_allocator>::value,
"rebinding an allocator should not change exception guarantees");
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index e59c210654caa..3731d3f6cf6d1 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -648,13 +648,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
diff er from user-specified type; otherwise overload resolution breaks");
diff --git a/libcxx/include/list b/libcxx/include/list
index 57e5c05da9f06..1678559a841dd 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -673,6 +673,7 @@ class _LIBCPP_TEMPLATE_VIS list : private __list_imp<_Tp, _Alloc> {
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");
typedef value_type& reference;
@@ -691,10 +692,6 @@ 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");
-
_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) {}
_LIBCPP_HIDE_FROM_ABI explicit list(size_type __n);
diff --git a/libcxx/include/map b/libcxx/include/map
index c44e75a1eb7e5..4b2f3fc71cbfe 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -997,9 +997,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_;
@@ -1656,6 +1654,7 @@ public:
typedef value_type& reference;
typedef const value_type& const_reference;
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
static_assert(is_same<typename allocator_type::value_type, value_type>::value,
"Allocator::value_type must be same type as value_type");
@@ -1681,10 +1680,6 @@ 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");
-
__base __tree_;
public:
diff --git a/libcxx/include/set b/libcxx/include/set
index c74d5d8d4cf02..9a2eb12d0a25a 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 54d24c88a9c3f..9a52ab6aef41e 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -780,10 +780,7 @@ public:
"traits_type::char_type must be the same type as CharT");
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 a243689b9dc86..7c31c4fce26b0 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -1057,9 +1057,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, "");
@@ -1839,6 +1837,7 @@ public:
typedef pair<const key_type, mapped_type> value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
+ 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");
@@ -1862,10 +1861,6 @@ private:
static_assert(is_same<typename __node_traits::size_type, typename __alloc_traits::size_type>::value,
"Allocator uses
diff erent size_type for
diff erent 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");
-
public:
typedef typename __alloc_traits::pointer pointer;
typedef typename __alloc_traits::const_pointer const_pointer;
diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index 5813e38a41f0d..3297294a893f8 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -588,13 +588,10 @@ public:
typedef __type_identity_t<_Alloc> allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
+ 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");
-
private:
typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
diff --git a/libcxx/include/vector b/libcxx/include/vector
index 014971b4a680e..299ad8c9b23f2 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -415,13 +415,10 @@ public:
vector,
void>;
+ static_assert(__check_valid_allocator<allocator_type>::value, "");
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");
-
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector()
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) {}
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(const allocator_type& __a)
More information about the libcxx-commits
mailing list