[libcxx-commits] [libcxx] d7d586e - [libc++] static_assert that rebinding the allocator works as expected

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Tue Oct 11 07:47:51 PDT 2022


Author: Nikolas Klauser
Date: 2022-10-11T16:47:42+02:00
New Revision: d7d586e5a7d71082200231a7cd407cae50924f9c

URL: https://github.com/llvm/llvm-project/commit/d7d586e5a7d71082200231a7cd407cae50924f9c
DIFF: https://github.com/llvm/llvm-project/commit/d7d586e5a7d71082200231a7cd407cae50924f9c.diff

LOG: [libc++] static_assert that rebinding the allocator works as expected

Reviewed By: ldionne, #libc

Spies: libcxx-commits

Differential Revision: https://reviews.llvm.org/D133638

Added: 
    

Modified: 
    libcxx/include/__functional/function.h
    libcxx/include/__hash_table
    libcxx/include/__memory/allocator_traits.h
    libcxx/include/__tree
    libcxx/include/deque
    libcxx/include/ext/hash_map
    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/__functional/function.h b/libcxx/include/__functional/function.h
index eb38ae8e5aa50..7d29a48594931 100644
--- a/libcxx/include/__functional/function.h
+++ b/libcxx/include/__functional/function.h
@@ -196,9 +196,7 @@ class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
     __alloc_func* __clone() const
     {
         typedef allocator_traits<_Alloc> __alloc_traits;
-        typedef
-            typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
-                _AA;
+        typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA;
         _AA __a(__f_.second());
         typedef __allocator_destructor<_AA> _Dp;
         unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -211,8 +209,7 @@ class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)>
 
     static void __destroy_and_delete(__alloc_func* __f) {
       typedef allocator_traits<_Alloc> __alloc_traits;
-      typedef typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type
-          _FunAlloc;
+      typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc;
       _FunAlloc __a(__f->__get_allocator());
       __f->destroy();
       __a.deallocate(__f, 1);
@@ -325,7 +322,7 @@ __base<_Rp(_ArgTypes...)>*
 __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.__get_allocator());
     typedef __allocator_destructor<_Ap> _Dp;
     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -352,7 +349,7 @@ void
 __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.__get_allocator());
     __f_.destroy();
     __a.deallocate(this, 1);
@@ -411,8 +408,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)>
     {
         typedef allocator_traits<_Alloc> __alloc_traits;
         typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
-        typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
-            _FunAlloc;
+        typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
 
         if (__function::__not_null(__f))
         {
@@ -752,8 +748,7 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
     {
         typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun;
         typedef allocator_traits<_Alloc> __alloc_traits;
-        typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type
-            _FunAlloc;
+        typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc;
 
         if (__function::__not_null(__f))
         {
@@ -1353,7 +1348,7 @@ __base<_Rp()>*
 __func<_Fp, _Alloc, _Rp()>::__clone() const
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.second());
     typedef __allocator_destructor<_Ap> _Dp;
     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -1380,7 +1375,7 @@ void
 __func<_Fp, _Alloc, _Rp()>::destroy_deallocate()
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.second());
     __f_.~__compressed_pair<_Fp, _Alloc>();
     __a.deallocate(this, 1);
@@ -1439,7 +1434,7 @@ __base<_Rp(_A0)>*
 __func<_Fp, _Alloc, _Rp(_A0)>::__clone() const
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.second());
     typedef __allocator_destructor<_Ap> _Dp;
     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -1466,7 +1461,7 @@ void
 __func<_Fp, _Alloc, _Rp(_A0)>::destroy_deallocate()
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.second());
     __f_.~__compressed_pair<_Fp, _Alloc>();
     __a.deallocate(this, 1);
@@ -1525,7 +1520,7 @@ __base<_Rp(_A0, _A1)>*
 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::__clone() const
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.second());
     typedef __allocator_destructor<_Ap> _Dp;
     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -1552,7 +1547,7 @@ void
 __func<_Fp, _Alloc, _Rp(_A0, _A1)>::destroy_deallocate()
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.second());
     __f_.~__compressed_pair<_Fp, _Alloc>();
     __a.deallocate(this, 1);
@@ -1611,7 +1606,7 @@ __base<_Rp(_A0, _A1, _A2)>*
 __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::__clone() const
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.second());
     typedef __allocator_destructor<_Ap> _Dp;
     unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -1638,7 +1633,7 @@ void
 __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)>::destroy_deallocate()
 {
     typedef allocator_traits<_Alloc> __alloc_traits;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap;
+    typedef __rebind_alloc<__alloc_traits, __func> _Ap;
     _Ap __a(__f_.second());
     __f_.~__compressed_pair<_Fp, _Alloc>();
     __a.deallocate(this, 1);
@@ -1814,7 +1809,7 @@ function<_Rp()>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
         }
         else
         {
-            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
+            typedef __rebind_alloc<__alloc_traits, _FF> _Ap;
             _Ap __a(__a0);
             typedef __allocator_destructor<_Ap> _Dp;
             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -2092,7 +2087,7 @@ function<_Rp(_A0)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
         }
         else
         {
-            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
+            typedef __rebind_alloc<__alloc_traits, _FF> _Ap;
             _Ap __a(__a0);
             typedef __allocator_destructor<_Ap> _Dp;
             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -2370,7 +2365,7 @@ function<_Rp(_A0, _A1)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f,
         }
         else
         {
-            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
+            typedef __rebind_alloc<__alloc_traits, _FF> _Ap;
             _Ap __a(__a0);
             typedef __allocator_destructor<_Ap> _Dp;
             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
@@ -2648,7 +2643,7 @@ function<_Rp(_A0, _A1, _A2)>::function(allocator_arg_t, const _Alloc& __a0, _Fp
         }
         else
         {
-            typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;
+            typedef __rebind_alloc<__alloc_traits, _FF> _Ap;
             _Ap __a(__a0);
             typedef __allocator_destructor<_Ap> _Dp;
             unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));

diff  --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index 50439926dc531..d6af75e9e0f03 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -898,7 +898,7 @@ public:
     // Create __node
 
     typedef typename _NodeTypes::__node_type __node;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
+    typedef __rebind_alloc<__alloc_traits, __node>   __node_allocator;
     typedef allocator_traits<__node_allocator>       __node_traits;
     typedef typename _NodeTypes::__void_pointer      __void_pointer;
     typedef typename _NodeTypes::__node_pointer      __node_pointer;
@@ -913,15 +913,14 @@ private:
     // the pointer using 'pointer_traits'.
     static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
                   "Allocator does not rebind pointers in a sane manner.");
-    typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type
-        __node_base_allocator;
+    typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator;
     typedef allocator_traits<__node_base_allocator> __node_base_traits;
     static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
                  "Allocator does not rebind pointers in a sane manner.");
 
 private:
 
-    typedef typename __rebind_alloc_helper<__node_traits, __next_pointer>::type __pointer_allocator;
+    typedef __rebind_alloc<__node_traits, __next_pointer>  __pointer_allocator;
     typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter;
     typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list;
     typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;

diff  --git a/libcxx/include/__memory/allocator_traits.h b/libcxx/include/__memory/allocator_traits.h
index cfc636dd8cb2c..619fe112a1e34 100644
--- a/libcxx/include/__memory/allocator_traits.h
+++ b/libcxx/include/__memory/allocator_traits.h
@@ -347,14 +347,13 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
     }
 };
 
-template <class _Traits, class _Tp>
-struct __rebind_alloc_helper {
 #ifndef _LIBCPP_CXX03_LANG
-    using type _LIBCPP_NODEBUG = typename _Traits::template rebind_alloc<_Tp>;
+template <class _Traits, class _Tp>
+using __rebind_alloc _LIBCPP_NODEBUG = typename _Traits::template rebind_alloc<_Tp>;
 #else
-    using type = typename _Traits::template rebind_alloc<_Tp>::other;
+template <class _Traits, class _Tp>
+using __rebind_alloc = typename _Traits::template rebind_alloc<_Tp>::other;
 #endif
-};
 
 // __is_default_allocator
 template <class _Tp>

diff  --git a/libcxx/include/__tree b/libcxx/include/__tree
index cbdff3c1ea54a..05a3da158098c 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -1021,7 +1021,7 @@ public:
     typedef typename _NodeTypes::__parent_pointer      __parent_pointer;
     typedef typename _NodeTypes::__iter_pointer        __iter_pointer;
 
-    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
+    typedef __rebind_alloc<__alloc_traits, __node> __node_allocator;
     typedef allocator_traits<__node_allocator>         __node_traits;
 
 private:
@@ -1030,8 +1030,7 @@ private:
     // the pointer using 'pointer_traits'.
     static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value),
                   "Allocator does not rebind pointers in a sane manner.");
-    typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type
-        __node_base_allocator;
+    typedef __rebind_alloc<__node_traits, __node_base> __node_base_allocator;
     typedef allocator_traits<__node_base_allocator> __node_base_traits;
     static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value),
                  "Allocator does not rebind pointers in a sane manner.");

diff  --git a/libcxx/include/deque b/libcxx/include/deque
index c315fd24cd3cc..b6e092b396370 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -956,8 +956,8 @@ public:
   using pointer       = typename __alloc_traits::pointer;
   using const_pointer = typename __alloc_traits::const_pointer;
 
-  using __pointer_allocator       = typename __rebind_alloc_helper<__alloc_traits, pointer>::type;
-  using __const_pointer_allocator = typename __rebind_alloc_helper<__alloc_traits, const_pointer>::type;
+  using __pointer_allocator       = __rebind_alloc<__alloc_traits, pointer>;
+  using __const_pointer_allocator = __rebind_alloc<__alloc_traits, const_pointer>;
   using __map                     = __split_buffer<pointer, __pointer_allocator>;
   using __map_alloc_traits        = allocator_traits<__pointer_allocator>;
   using __map_pointer             = typename __map_alloc_traits::pointer;
@@ -972,8 +972,9 @@ public:
   using reverse_iterator       = std::reverse_iterator<iterator>;
   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
-  static_assert(is_same<allocator_type, typename __rebind_alloc_helper<__alloc_traits, value_type>::type>::value,
-                "rebinding an allocator to value_type should result in the original allocator");
+  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 excpetion guarantees");

diff  --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map
index e4b61416f71c0..48186aed0b6a6 100644
--- a/libcxx/include/ext/hash_map
+++ b/libcxx/include/ext/hash_map
@@ -483,8 +483,7 @@ private:
     typedef std::pair<key_type, mapped_type>                    __value_type;
     typedef __hash_map_hasher<__value_type, hasher>   __hasher;
     typedef __hash_map_equal<__value_type, key_equal> __key_equal;
-    typedef typename std::__rebind_alloc_helper<
-        std::allocator_traits<allocator_type>, __value_type>::type __allocator_type;
+    typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type;
 
     typedef std::__hash_table<__value_type, __hasher,
                          __key_equal,  __allocator_type>   __table;
@@ -757,7 +756,7 @@ private:
     typedef std::pair<key_type, mapped_type>               __value_type;
     typedef __hash_map_hasher<__value_type, hasher>   __hasher;
     typedef __hash_map_equal<__value_type, key_equal> __key_equal;
-    typedef typename std::__rebind_alloc_helper<std::allocator_traits<allocator_type>, __value_type>::type __allocator_type;
+    typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type;
 
     typedef std::__hash_table<__value_type, __hasher,
                          __key_equal,  __allocator_type>   __table;

diff  --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index 5890fdd22b277..1f817ae8927fd 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -474,13 +474,11 @@ protected:
     typedef typename allocator_traits<allocator_type>::void_pointer  void_pointer;
     typedef __forward_list_node<value_type, void_pointer>            __node;
     typedef __begin_node_of<value_type, void_pointer>                __begin_node;
-    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator;
+    typedef __rebind_alloc<allocator_traits<allocator_type>, __node> __node_allocator;
     typedef allocator_traits<__node_allocator>        __node_traits;
     typedef typename __node_traits::pointer           __node_pointer;
 
-    typedef typename __rebind_alloc_helper<
-        allocator_traits<allocator_type>, __begin_node
-    >::type                                           __begin_node_allocator;
+    typedef __rebind_alloc<allocator_traits<allocator_type>, __begin_node> __begin_node_allocator;
     typedef typename allocator_traits<__begin_node_allocator>::pointer
                                                       __begin_node_pointer;
 
@@ -488,6 +486,10 @@ protected:
                   "internal allocator type must 
diff er from user-specified "
                   "type; otherwise overload resolution breaks");
 
+    static_assert(is_same<allocator_type, __rebind_alloc<__node_traits, value_type> >::value,
+                  "[allocator.requirements] states that rebinding an allocator to the same type should result in the "
+                  "original allocator");
+
     __compressed_pair<__begin_node, __node_allocator> __before_begin_;
 
     _LIBCPP_INLINE_VISIBILITY

diff  --git a/libcxx/include/list b/libcxx/include/list
index edd56e5e2ca45..d3c47bb1d6155 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -551,7 +551,7 @@ protected:
     typedef __list_const_iterator<value_type, __void_pointer>       const_iterator;
     typedef __list_node_base<value_type, __void_pointer>            __node_base;
     typedef __list_node<value_type, __void_pointer>                 __node;
-    typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator;
+    typedef __rebind_alloc<__alloc_traits, __node>                  __node_allocator;
     typedef allocator_traits<__node_allocator>                       __node_alloc_traits;
     typedef typename __node_alloc_traits::pointer                    __node_pointer;
     typedef typename __node_alloc_traits::pointer                    __node_const_pointer;
@@ -562,7 +562,7 @@ protected:
     typedef typename __alloc_traits::const_pointer                   const_pointer;
     typedef typename __alloc_traits::
diff erence_type                 
diff erence_type;
 
-    typedef typename __rebind_alloc_helper<__alloc_traits, __node_base>::type __node_base_allocator;
+    typedef __rebind_alloc<__alloc_traits, __node_base>               __node_base_allocator;
     typedef typename allocator_traits<__node_base_allocator>::pointer __node_base_pointer;
     static_assert((!is_same<allocator_type, __node_allocator>::value),
                   "internal allocator type must 
diff er from user-specified "
@@ -841,6 +841,10 @@ 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_INLINE_VISIBILITY
     list()
         _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value)

diff  --git a/libcxx/include/map b/libcxx/include/map
index 8f01d6303407e..2d55b69dc9267 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -999,12 +999,15 @@ private:
 
     typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
     typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
-    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
-                                                 __value_type>::type __allocator_type;
+    typedef __rebind_alloc<allocator_traits<allocator_type>, __value_type> __allocator_type;
     typedef __tree<__value_type, __vc, __allocator_type>   __base;
     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:
@@ -1776,12 +1779,15 @@ private:
 
     typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
     typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
-    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
-                                                 __value_type>::type __allocator_type;
+    typedef __rebind_alloc<allocator_traits<allocator_type>, __value_type> __allocator_type;
     typedef __tree<__value_type, __vc, __allocator_type>            __base;
     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 1f7f25514e4ce..3933ef22c221e 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -531,6 +531,10 @@ 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");
+
     __base __tree_;
 
 public:
@@ -1064,6 +1068,10 @@ 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");
+
     __base __tree_;
 
 public:

diff  --git a/libcxx/include/string b/libcxx/include/string
index 31d053c60467a..652fa32070352 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -686,6 +686,10 @@ 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");
+
     typedef __wrap_iter<pointer>                         iterator;
     typedef __wrap_iter<const_pointer>                   const_iterator;
     typedef std::reverse_iterator<iterator>              reverse_iterator;

diff  --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map
index 3d67a3f0a1f7d..a727c36223e5e 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -1041,8 +1041,7 @@ private:
     typedef __hash_value_type<key_type, mapped_type>                          __value_type;
     typedef __unordered_map_hasher<key_type, __value_type, hasher, key_equal> __hasher;
     typedef __unordered_map_equal<key_type, __value_type, key_equal, hasher>  __key_equal;
-    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
-                                                 __value_type>::type          __allocator_type;
+    typedef __rebind_alloc<allocator_traits<allocator_type>, __value_type>    __allocator_type;
 
     typedef __hash_table<__value_type, __hasher,
                          __key_equal,  __allocator_type>   __table;
@@ -1059,6 +1058,10 @@ 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((is_same<typename __table::__container_value_type, value_type>::value), "");
     static_assert((is_same<typename __table::__node_value_type, __value_type>::value), "");
 public:
@@ -1931,8 +1934,7 @@ private:
     typedef __hash_value_type<key_type, mapped_type>                          __value_type;
     typedef __unordered_map_hasher<key_type, __value_type, hasher, key_equal> __hasher;
     typedef __unordered_map_equal<key_type, __value_type, key_equal, hasher>  __key_equal;
-    typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>,
-                                                 __value_type>::type          __allocator_type;
+    typedef __rebind_alloc<allocator_traits<allocator_type>, __value_type>    __allocator_type;
 
     typedef __hash_table<__value_type, __hasher,
                          __key_equal,  __allocator_type>   __table;
@@ -1949,7 +1951,12 @@ 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");
-public:
+
+    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;
     typedef typename __table::size_type              size_type;

diff  --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index 4cfe7fa7ebd0e..4786a8a8c5f18 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -515,7 +515,11 @@ public:
     static_assert((is_same<value_type, typename allocator_type::value_type>::value),
                   "Invalid allocator::value_type");
 
-private:
+    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;
 
     __table __table_;

diff  --git a/libcxx/include/vector b/libcxx/include/vector
index 1ff6f4a147bb7..b5a97c66cf53a 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -358,6 +358,10 @@ 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");
+
     _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
     vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
     {
@@ -2009,7 +2013,7 @@ public:
     typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
 
 private:
-    typedef typename __rebind_alloc_helper<__alloc_traits, __storage_type>::type __storage_allocator;
+    typedef __rebind_alloc<__alloc_traits, __storage_type> __storage_allocator;
     typedef allocator_traits<__storage_allocator>    __storage_traits;
     typedef typename __storage_traits::pointer       __storage_pointer;
     typedef typename __storage_traits::const_pointer __const_storage_pointer;


        


More information about the libcxx-commits mailing list