Skip to content

Commit 442deb1

Browse files
huixie90AlexisPerry
authored andcommitted
[libc++] Move allocator assertion into allocator_traits (llvm#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.
1 parent f675e70 commit 442deb1

File tree

10 files changed

+24
-46
lines changed

10 files changed

+24
-46
lines changed

libcxx/include/__memory/allocator_traits.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <__type_traits/enable_if.h>
1717
#include <__type_traits/is_constructible.h>
1818
#include <__type_traits/is_empty.h>
19+
#include <__type_traits/is_same.h>
1920
#include <__type_traits/make_unsigned.h>
2021
#include <__type_traits/remove_reference.h>
2122
#include <__type_traits/void_t.h>
@@ -372,6 +373,14 @@ template <class _Traits, class _Tp>
372373
using __rebind_alloc = typename _Traits::template rebind_alloc<_Tp>::other;
373374
#endif
374375

376+
template <class _Alloc>
377+
struct __check_valid_allocator : true_type {
378+
using _Traits = std::allocator_traits<_Alloc>;
379+
static_assert(is_same<_Alloc, __rebind_alloc<_Traits, typename _Traits::value_type> >::value,
380+
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
381+
"original allocator");
382+
};
383+
375384
// __is_default_allocator
376385
template <class _Tp>
377386
struct __is_default_allocator : false_type {};

libcxx/include/deque

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -449,11 +449,11 @@ public:
449449

450450
using value_type = _Tp;
451451

452-
static_assert(is_same<typename _Allocator::value_type, value_type>::value,
453-
"Allocator::value_type must be same type as value_type");
454-
455452
using allocator_type = _Allocator;
456453
using __alloc_traits = allocator_traits<allocator_type>;
454+
static_assert(__check_valid_allocator<allocator_type>::value, "");
455+
static_assert(is_same<typename allocator_type::value_type, value_type>::value,
456+
"Allocator::value_type must be same type as value_type");
457457

458458
using size_type = typename __alloc_traits::size_type;
459459
using difference_type = typename __alloc_traits::difference_type;
@@ -488,9 +488,6 @@ public:
488488
deque,
489489
void>;
490490

491-
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
492-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
493-
"original allocator");
494491
static_assert(is_nothrow_default_constructible<allocator_type>::value ==
495492
is_nothrow_default_constructible<__pointer_allocator>::value,
496493
"rebinding an allocator should not change exception guarantees");

libcxx/include/forward_list

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -648,13 +648,11 @@ public:
648648
typedef _Tp value_type;
649649
typedef _Alloc allocator_type;
650650

651+
static_assert(__check_valid_allocator<allocator_type>::value, "");
652+
651653
static_assert(is_same<value_type, typename allocator_type::value_type>::value,
652654
"Allocator::value_type must be same type as value_type");
653655

654-
static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
655-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
656-
"original allocator");
657-
658656
static_assert(!is_same<allocator_type, __node_allocator>::value,
659657
"internal allocator type must differ from user-specified type; otherwise overload resolution breaks");
660658

libcxx/include/list

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,7 @@ class _LIBCPP_TEMPLATE_VIS list : private __list_imp<_Tp, _Alloc> {
673673
public:
674674
typedef _Tp value_type;
675675
typedef _Alloc allocator_type;
676+
static_assert(__check_valid_allocator<allocator_type>::value);
676677
static_assert(is_same<value_type, typename allocator_type::value_type>::value,
677678
"Allocator::value_type must be same type as value_type");
678679
typedef value_type& reference;
@@ -691,10 +692,6 @@ public:
691692
typedef void __remove_return_type;
692693
#endif
693694

694-
static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
695-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
696-
"original allocator");
697-
698695
_LIBCPP_HIDE_FROM_ABI list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {}
699696
_LIBCPP_HIDE_FROM_ABI explicit list(const allocator_type& __a) : base(__a) {}
700697
_LIBCPP_HIDE_FROM_ABI explicit list(size_type __n);

libcxx/include/map

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -997,9 +997,7 @@ private:
997997
typedef typename __base::__node_traits __node_traits;
998998
typedef allocator_traits<allocator_type> __alloc_traits;
999999

1000-
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
1001-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
1002-
"original allocator");
1000+
static_assert(__check_valid_allocator<allocator_type>::value, "");
10031001

10041002
__base __tree_;
10051003

@@ -1656,6 +1654,7 @@ public:
16561654
typedef value_type& reference;
16571655
typedef const value_type& const_reference;
16581656

1657+
static_assert(__check_valid_allocator<allocator_type>::value, "");
16591658
static_assert(is_same<typename allocator_type::value_type, value_type>::value,
16601659
"Allocator::value_type must be same type as value_type");
16611660

@@ -1681,10 +1680,6 @@ private:
16811680
typedef typename __base::__node_traits __node_traits;
16821681
typedef allocator_traits<allocator_type> __alloc_traits;
16831682

1684-
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
1685-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
1686-
"original allocator");
1687-
16881683
__base __tree_;
16891684

16901685
public:

libcxx/include/set

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -578,9 +578,7 @@ private:
578578
typedef __tree<value_type, value_compare, allocator_type> __base;
579579
typedef allocator_traits<allocator_type> __alloc_traits;
580580

581-
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
582-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
583-
"original allocator");
581+
static_assert(__check_valid_allocator<allocator_type>::value, "");
584582

585583
__base __tree_;
586584

@@ -1035,9 +1033,7 @@ private:
10351033
typedef __tree<value_type, value_compare, allocator_type> __base;
10361034
typedef allocator_traits<allocator_type> __alloc_traits;
10371035

1038-
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
1039-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
1040-
"original allocator");
1036+
static_assert(__check_valid_allocator<allocator_type>::value, "");
10411037

10421038
__base __tree_;
10431039

libcxx/include/string

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -780,10 +780,7 @@ public:
780780
"traits_type::char_type must be the same type as CharT");
781781
static_assert(is_same<typename allocator_type::value_type, value_type>::value,
782782
"Allocator::value_type must be same type as value_type");
783-
784-
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
785-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
786-
"original allocator");
783+
static_assert(__check_valid_allocator<allocator_type>::value, "");
787784

788785
// TODO: Implement iterator bounds checking without requiring the global database.
789786
typedef __wrap_iter<pointer> iterator;

libcxx/include/unordered_map

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,9 +1057,7 @@ private:
10571057
typedef unique_ptr<__node, _Dp> __node_holder;
10581058
typedef allocator_traits<allocator_type> __alloc_traits;
10591059

1060-
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
1061-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
1062-
"original allocator");
1060+
static_assert(__check_valid_allocator<allocator_type>::value, "");
10631061

10641062
static_assert(is_same<typename __table::__container_value_type, value_type>::value, "");
10651063
static_assert(is_same<typename __table::__node_value_type, __value_type>::value, "");
@@ -1839,6 +1837,7 @@ public:
18391837
typedef pair<const key_type, mapped_type> value_type;
18401838
typedef value_type& reference;
18411839
typedef const value_type& const_reference;
1840+
static_assert(__check_valid_allocator<allocator_type>::value, "");
18421841
static_assert(is_same<value_type, typename allocator_type::value_type>::value,
18431842
"Allocator::value_type must be same type as value_type");
18441843

@@ -1862,10 +1861,6 @@ private:
18621861
static_assert(is_same<typename __node_traits::size_type, typename __alloc_traits::size_type>::value,
18631862
"Allocator uses different size_type for different types");
18641863

1865-
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
1866-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
1867-
"original allocator");
1868-
18691864
public:
18701865
typedef typename __alloc_traits::pointer pointer;
18711866
typedef typename __alloc_traits::const_pointer const_pointer;

libcxx/include/unordered_set

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -588,13 +588,10 @@ public:
588588
typedef __type_identity_t<_Alloc> allocator_type;
589589
typedef value_type& reference;
590590
typedef const value_type& const_reference;
591+
static_assert(__check_valid_allocator<allocator_type>::value, "");
591592
static_assert(is_same<value_type, typename allocator_type::value_type>::value,
592593
"Allocator::value_type must be same type as value_type");
593594

594-
static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value,
595-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
596-
"original allocator");
597-
598595
private:
599596
typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
600597

libcxx/include/vector

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,13 +415,10 @@ public:
415415
vector,
416416
void>;
417417

418+
static_assert(__check_valid_allocator<allocator_type>::value, "");
418419
static_assert(is_same<typename allocator_type::value_type, value_type>::value,
419420
"Allocator::value_type must be same type as value_type");
420421

421-
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
422-
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
423-
"original allocator");
424-
425422
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector()
426423
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) {}
427424
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(const allocator_type& __a)

0 commit comments

Comments
 (0)