Skip to content

[libc++] Move allocator assertion into allocator_traits #94750

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

Merged
merged 1 commit into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions libcxx/include/__memory/allocator_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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 {};
Expand Down
9 changes: 3 additions & 6 deletions libcxx/include/deque
Original file line number Diff line number Diff line change
Expand Up @@ -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 difference_type = typename __alloc_traits::difference_type;
Expand Down Expand Up @@ -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");
Expand Down
6 changes: 2 additions & 4 deletions libcxx/include/forward_list
Original file line number Diff line number Diff line change
Expand Up @@ -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 differ from user-specified type; otherwise overload resolution breaks");

Expand Down
5 changes: 1 addition & 4 deletions libcxx/include/list
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
9 changes: 2 additions & 7 deletions libcxx/include/map
Original file line number Diff line number Diff line change
Expand Up @@ -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_;

Expand Down Expand Up @@ -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");

Expand All @@ -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:
Expand Down
8 changes: 2 additions & 6 deletions libcxx/include/set
Original file line number Diff line number Diff line change
Expand Up @@ -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_;

Expand Down Expand Up @@ -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_;

Expand Down
5 changes: 1 addition & 4 deletions libcxx/include/string
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
9 changes: 2 additions & 7 deletions libcxx/include/unordered_map
Original file line number Diff line number Diff line change
Expand Up @@ -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, "");
Expand Down Expand Up @@ -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");

Expand All @@ -1862,10 +1861,6 @@ 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");

public:
typedef typename __alloc_traits::pointer pointer;
typedef typename __alloc_traits::const_pointer const_pointer;
Expand Down
5 changes: 1 addition & 4 deletions libcxx/include/unordered_set
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
5 changes: 1 addition & 4 deletions libcxx/include/vector
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading