Implement full support for non-pointer pointers in custom allocators for forward_list.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@184759 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/forward_list b/include/forward_list
index 0cbf2fd..88bf75f 100644
--- a/include/forward_list
+++ b/include/forward_list
@@ -232,7 +232,7 @@
     typedef forward_iterator_tag                              iterator_category;
     typedef typename pointer_traits<__node_pointer>::element_type::value_type
                                                               value_type;
-    typedef value_type& reference;
+    typedef value_type&                                       reference;
     typedef typename pointer_traits<__node_pointer>::difference_type
                                                               difference_type;
     typedef typename pointer_traits<__node_pointer>::template
@@ -249,7 +249,7 @@
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {return __ptr_->__value_;}
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return &__ptr_->__value_;}
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
     __forward_list_iterator& operator++()
@@ -303,7 +303,7 @@
 public:
     typedef forward_iterator_tag                              iterator_category;
     typedef typename __node::value_type                       value_type;
-    typedef const value_type& reference;
+    typedef const value_type&                                 reference;
     typedef typename pointer_traits<__node_const_pointer>::difference_type
                                                               difference_type;
     typedef typename pointer_traits<__node_const_pointer>::template
@@ -323,7 +323,7 @@
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {return __ptr_->__value_;}
     _LIBCPP_INLINE_VISIBILITY
-    pointer operator->() const {return &__ptr_->__value_;}
+    pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
     __forward_list_const_iterator& operator++()
@@ -368,18 +368,27 @@
                                                       __node_allocator;
     typedef allocator_traits<__node_allocator>        __node_traits;
     typedef typename __node_traits::pointer           __node_pointer;
-    typedef typename __node_traits::const_pointer     __node_const_pointer;
+    typedef typename __node_traits::pointer           __node_const_pointer;
+
+    typedef typename allocator_traits<allocator_type>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+                rebind_alloc<__begin_node>
+#else
+                rebind_alloc<__begin_node>::other
+#endif
+                                                      __begin_node_allocator;
+    typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer;
 
     __compressed_pair<__begin_node, __node_allocator> __before_begin_;
 
     _LIBCPP_INLINE_VISIBILITY
     __node_pointer        __before_begin() _NOEXCEPT
-        {return pointer_traits<__node_pointer>::pointer_to(
-                                static_cast<__node&>(__before_begin_.first()));}
+        {return static_cast<__node_pointer>(pointer_traits<__begin_node_pointer>::
+                                        pointer_to(__before_begin_.first()));}
     _LIBCPP_INLINE_VISIBILITY
     __node_const_pointer  __before_begin() const _NOEXCEPT
-        {return pointer_traits<__node_const_pointer>::pointer_to(
-                          static_cast<const __node&>(__before_begin_.first()));}
+        {return static_cast<__node_const_pointer>(pointer_traits<__begin_node_pointer>::
+                                        pointer_to(const_cast<__begin_node&>(__before_begin_.first())));}
 
     _LIBCPP_INLINE_VISIBILITY
           __node_allocator& __alloc() _NOEXCEPT
@@ -389,7 +398,7 @@
         {return __before_begin_.second();}
 
     typedef __forward_list_iterator<__node_pointer>             iterator;
-    typedef __forward_list_const_iterator<__node_const_pointer> const_iterator;
+    typedef __forward_list_const_iterator<__node_pointer>       const_iterator;
 
     _LIBCPP_INLINE_VISIBILITY
     __forward_list_base()
@@ -1050,7 +1059,7 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args)
 {
-    __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer const __r = __p.__ptr_;
     __node_allocator& __a = base::__alloc();
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
@@ -1067,7 +1076,7 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v)
 {
-    __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer const __r = __p.__ptr_;
     __node_allocator& __a = base::__alloc();
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
@@ -1083,7 +1092,7 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v)
 {
-    __node_pointer const __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer const __r = __p.__ptr_;
     __node_allocator& __a = base::__alloc();
     typedef __allocator_destructor<__node_allocator> _Dp;
     unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1));
@@ -1098,7 +1107,7 @@
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n,
                                         const value_type& __v)
 {
-    __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer __r = __p.__ptr_;
     if (__n > 0)
     {
         __node_allocator& __a = base::__alloc();
@@ -1148,7 +1157,7 @@
 forward_list<_Tp, _Alloc>::insert_after(const_iterator __p,
                                         _InputIterator __f, _InputIterator __l)
 {
-    __node_pointer __r = const_cast<__node_pointer>(__p.__ptr_);
+    __node_pointer __r = __p.__ptr_;
     if (__f != __l)
     {
         __node_allocator& __a = base::__alloc();
@@ -1192,7 +1201,7 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f)
 {
-    __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
+    __node_pointer __p = __f.__ptr_;
     __node_pointer __n = __p->__next_;
     __p->__next_ = __n->__next_;
     __node_allocator& __a = base::__alloc();
@@ -1205,10 +1214,10 @@
 typename forward_list<_Tp, _Alloc>::iterator
 forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l)
 {
-    __node_pointer __e = const_cast<__node_pointer>(__l.__ptr_);
+    __node_pointer __e = __l.__ptr_;
     if (__f != __l)
     {
-        __node_pointer __p = const_cast<__node_pointer>(__f.__ptr_);
+        __node_pointer __p = __f.__ptr_;
         __node_pointer __n = __p->__next_;
         if (__n != __e)
         {
@@ -1302,12 +1311,10 @@
             const_iterator __lm1 = __x.before_begin();
             while (__lm1.__ptr_->__next_ != nullptr)
                 ++__lm1;
-            const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
-                const_cast<__node_pointer>(__p.__ptr_)->__next_;
+            __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
         }
-        const_cast<__node_pointer>(__p.__ptr_)->__next_ =
-            const_cast<__node_pointer>(__x.__before_begin())->__next_;
-        const_cast<__node_pointer>(__x.__before_begin())->__next_ = nullptr;
+        __p.__ptr_->__next_ = __x.__before_begin()->__next_;
+        __x.__before_begin()->__next_ = nullptr;
     }
 }
 
@@ -1320,12 +1327,9 @@
     const_iterator __lm1 = _VSTD::next(__i);
     if (__p != __i && __p != __lm1)
     {
-        const_cast<__node_pointer>(__i.__ptr_)->__next_ =
-            const_cast<__node_pointer>(__lm1.__ptr_)->__next_;
-        const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
-            const_cast<__node_pointer>(__p.__ptr_)->__next_;
-        const_cast<__node_pointer>(__p.__ptr_)->__next_ =
-            const_cast<__node_pointer>(__lm1.__ptr_);
+        __i.__ptr_->__next_ = __lm1.__ptr_->__next_;
+        __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
+        __p.__ptr_->__next_ = __lm1.__ptr_;
     }
 }
 
@@ -1342,12 +1346,9 @@
             ++__lm1;
         if (__f != __lm1)
         {
-            const_cast<__node_pointer>(__lm1.__ptr_)->__next_ =
-                const_cast<__node_pointer>(__p.__ptr_)->__next_;
-            const_cast<__node_pointer>(__p.__ptr_)->__next_ =
-                const_cast<__node_pointer>(__f.__ptr_)->__next_;
-            const_cast<__node_pointer>(__f.__ptr_)->__next_ =
-                const_cast<__node_pointer>(__l.__ptr_);
+            __lm1.__ptr_->__next_ = __p.__ptr_->__next_;
+            __p.__ptr_->__next_ = __f.__ptr_->__next_;
+            __f.__ptr_->__next_ = __l.__ptr_;
         }
     }
 }