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

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@185093 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/__bit_reference b/include/__bit_reference
index 1621deb..8ff3bf6 100644
--- a/include/__bit_reference
+++ b/include/__bit_reference
@@ -333,7 +333,7 @@
     }
     // do middle whole words
     __storage_type __nw = __n / __bits_per_word;
-    _VSTD::memset(__first.__seg_, 0, __nw * sizeof(__storage_type));
+    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type));
     __n -= __nw * __bits_per_word;
     // do last partial word
     if (__n > 0)
@@ -363,7 +363,7 @@
     }
     // do middle whole words
     __storage_type __nw = __n / __bits_per_word;
-    _VSTD::memset(__first.__seg_, -1, __nw * sizeof(__storage_type));
+    _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type));
     __n -= __nw * __bits_per_word;
     // do last partial word
     if (__n > 0)
@@ -430,7 +430,9 @@
         // __first.__ctz_ == 0;
         // do middle words
         __storage_type __nw = __n / __bits_per_word;
-        _VSTD::memmove(__result.__seg_, __first.__seg_, __nw * sizeof(__storage_type));
+        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
+                       _VSTD::__to_raw_pointer(__first.__seg_),
+                       __nw * sizeof(__storage_type));
         __n -= __nw * __bits_per_word;
         __result.__seg_ += __nw;
         // do last word
@@ -569,7 +571,9 @@
         __storage_type __nw = __n / __bits_per_word;
         __result.__seg_ -= __nw;
         __last.__seg_ -= __nw;
-        _VSTD::memmove(__result.__seg_, __last.__seg_, __nw * sizeof(__storage_type));
+        _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_),
+                       _VSTD::__to_raw_pointer(__last.__seg_),
+                       __nw * sizeof(__storage_type));
         __n -= __nw * __bits_per_word;
         // do last word
         if (__n > 0)
@@ -870,6 +874,7 @@
 {
     typedef typename _Cp::difference_type difference_type;
     typedef typename _Cp::__storage_type  __storage_type;
+    typedef typename _Cp::__storage_pointer __storage_pointer;
     typedef typename _Cp::iterator        iterator;
     static const unsigned __bits_per_word = _Cp::__bits_per_word;
     static const unsigned _Np = 4;
@@ -880,9 +885,15 @@
     _LIBCPP_INLINE_VISIBILITY static difference_type capacity()
         {return static_cast<difference_type>(_Np * __bits_per_word);}
     _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {}
-    _LIBCPP_INLINE_VISIBILITY iterator begin() {return iterator(__word_, 0);}
-    _LIBCPP_INLINE_VISIBILITY iterator end()   {return iterator(__word_ + __size_ / __bits_per_word,
-                                                  static_cast<unsigned>(__size_ % __bits_per_word));}
+    _LIBCPP_INLINE_VISIBILITY iterator begin()
+    {
+        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0);
+    }
+    _LIBCPP_INLINE_VISIBILITY iterator end()
+    {
+        return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word,
+                                                  static_cast<unsigned>(__size_ % __bits_per_word));
+    }
 };
 
 template <class _Cp>
diff --git a/include/iterator b/include/iterator
index 3b078a2..dda053d 100644
--- a/include/iterator
+++ b/include/iterator
@@ -1135,7 +1135,14 @@
 #endif
         return *__i;
     }
-    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const _NOEXCEPT {return &(operator*());}
+    _LIBCPP_INLINE_VISIBILITY pointer  operator->() const _NOEXCEPT
+    {
+#if _LIBCPP_DEBUG_LEVEL >= 2
+        _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this),
+                       "Attempted to dereference a non-dereferenceable iterator");
+#endif
+        return (pointer)&reinterpret_cast<const volatile char&>(*__i);
+    }
     _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
diff --git a/include/vector b/include/vector
index e04c267..046d92d 100644
--- a/include/vector
+++ b/include/vector
@@ -365,12 +365,7 @@
         {return static_cast<size_type>(__end_cap() - __begin_);}
 
     _LIBCPP_INLINE_VISIBILITY
-    void __destruct_at_end(const_pointer __new_last) _NOEXCEPT
-        {__destruct_at_end(__new_last, false_type());}
-    _LIBCPP_INLINE_VISIBILITY
-    void __destruct_at_end(const_pointer __new_last, false_type) _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
-    void __destruct_at_end(const_pointer __new_last, true_type) _NOEXCEPT;
+    void __destruct_at_end(pointer __new_last) _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
     void __copy_assign_alloc(const __vector_base& __c)
@@ -437,43 +432,35 @@
 template <class _Tp, class _Allocator>
 _LIBCPP_INLINE_VISIBILITY inline
 void
-__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, false_type) _NOEXCEPT
+__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT
 {
     while (__new_last != __end_)
-        __alloc_traits::destroy(__alloc(), const_cast<pointer>(--__end_));
-}
-
-template <class _Tp, class _Allocator>
-_LIBCPP_INLINE_VISIBILITY inline
-void
-__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, true_type) _NOEXCEPT
-{
-    __end_ = const_cast<pointer>(__new_last);
+        __alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__end_));
 }
 
 template <class _Tp, class _Allocator>
 _LIBCPP_INLINE_VISIBILITY inline
 __vector_base<_Tp, _Allocator>::__vector_base()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-    : __begin_(0),
-      __end_(0),
-      __end_cap_(0)
+    : __begin_(nullptr),
+      __end_(nullptr),
+      __end_cap_(nullptr)
 {
 }
 
 template <class _Tp, class _Allocator>
 _LIBCPP_INLINE_VISIBILITY inline
 __vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a)
-    : __begin_(0),
-      __end_(0),
-      __end_cap_(0, __a)
+    : __begin_(nullptr),
+      __end_(nullptr),
+      __end_cap_(nullptr, __a)
 {
 }
 
 template <class _Tp, class _Allocator>
 __vector_base<_Tp, _Allocator>::~__vector_base()
 {
-    if (__begin_ != 0)
+    if (__begin_ != nullptr)
     {
         clear();
         __alloc_traits::deallocate(__alloc(), __begin_, capacity());
@@ -797,7 +784,7 @@
         _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);
     void __move_assign(vector& __c, false_type);
     _LIBCPP_INLINE_VISIBILITY
-    void __destruct_at_end(const_pointer __new_last) _NOEXCEPT
+    void __destruct_at_end(pointer __new_last) _NOEXCEPT
     {
 #if _LIBCPP_DEBUG_LEVEL >= 2
         __c_node* __c = __get_db()->__find_c_and_lock(this);
@@ -878,11 +865,11 @@
 void
 vector<_Tp, _Allocator>::deallocate() _NOEXCEPT
 {
-    if (this->__begin_ != 0)
+    if (this->__begin_ != nullptr)
     {
         clear();
         __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());
-        this->__begin_ = this->__end_ = this->__end_cap() = 0;
+        this->__begin_ = this->__end_ = this->__end_cap() = nullptr;
     }
 }
 
@@ -1171,7 +1158,7 @@
     this->__begin_ = __x.__begin_;
     this->__end_ = __x.__end_;
     this->__end_cap() = __x.__end_cap();
-    __x.__begin_ = __x.__end_ = __x.__end_cap() = 0;
+    __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;
 }
 
 template <class _Tp, class _Allocator>
@@ -1597,7 +1584,8 @@
 #endif
     _LIBCPP_ASSERT(__position != end(),
         "vector::erase(iterator) called with a non-dereferenceable iterator");
-    pointer __p = const_cast<pointer>(&*__position);
+    difference_type __ps = __position - cbegin();
+    pointer __p = this->__begin_ + __ps;
     iterator __r = __make_iter(__p);
     this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));
     return __r;
@@ -1943,9 +1931,9 @@
 bool
 vector<_Tp, _Allocator>::__invariants() const
 {
-    if (this->__begin_ == 0)
+    if (this->__begin_ == nullptr)
     {
-        if (this->__end_ != 0 || this->__end_cap() != 0)
+        if (this->__end_ != nullptr || this->__end_cap() != nullptr)
             return false;
     }
     else
@@ -2307,7 +2295,7 @@
         {return const_iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}
     _LIBCPP_INLINE_VISIBILITY
     iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT
-        {return iterator(const_cast<__storage_pointer>(__p.__seg_), __p.__ctz_);}
+        {return begin() + (__p - cbegin());}
 #endif  // _LIBCPP_DEBUG
 
     _LIBCPP_INLINE_VISIBILITY
@@ -2414,11 +2402,11 @@
 void
 vector<bool, _Allocator>::deallocate() _NOEXCEPT
 {
-    if (this->__begin_ != 0)
+    if (this->__begin_ != nullptr)
     {
         __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap());
         __invalidate_all_iterators();
-        this->__begin_ = 0;
+        this->__begin_ = nullptr;
         this->__size_ = this->__cap() = 0;
     }
 }
@@ -2481,7 +2469,7 @@
 _LIBCPP_INLINE_VISIBILITY inline
 vector<bool, _Allocator>::vector()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2490,7 +2478,7 @@
 template <class _Allocator>
 _LIBCPP_INLINE_VISIBILITY inline
 vector<bool, _Allocator>::vector(const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2498,7 +2486,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(size_type __n)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2511,7 +2499,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(size_type __n, const value_type& __x)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2524,7 +2512,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2540,7 +2528,7 @@
 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,
        typename enable_if<__is_input_iterator  <_InputIterator>::value &&
                          !__is_forward_iterator<_InputIterator>::value>::type*)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2554,7 +2542,7 @@
     }
     catch (...)
     {
-        if (__begin_ != 0)
+        if (__begin_ != nullptr)
             __storage_traits::deallocate(__alloc(), __begin_, __cap());
         __invalidate_all_iterators();
         throw;
@@ -2567,7 +2555,7 @@
 vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,
        typename enable_if<__is_input_iterator  <_InputIterator>::value &&
                          !__is_forward_iterator<_InputIterator>::value>::type*)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2581,7 +2569,7 @@
     }
     catch (...)
     {
-        if (__begin_ != 0)
+        if (__begin_ != nullptr)
             __storage_traits::deallocate(__alloc(), __begin_, __cap());
         __invalidate_all_iterators();
         throw;
@@ -2593,7 +2581,7 @@
 template <class _ForwardIterator>
 vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,
                                 typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2609,7 +2597,7 @@
 template <class _ForwardIterator>
 vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,
                                 typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2625,7 +2613,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(initializer_list<value_type> __il)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0)
 {
@@ -2639,7 +2627,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, static_cast<__storage_allocator>(__a))
 {
@@ -2656,7 +2644,7 @@
 template <class _Allocator>
 vector<bool, _Allocator>::~vector()
 {
-    if (__begin_ != 0)
+    if (__begin_ != nullptr)
         __storage_traits::deallocate(__alloc(), __begin_, __cap());
 #ifdef _LIBCPP_DEBUG
     __invalidate_all_iterators();
@@ -2665,7 +2653,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(const vector& __v)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, __storage_traits::select_on_container_copy_construction(__v.__alloc()))
 {
@@ -2678,7 +2666,7 @@
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, __a)
 {
@@ -2720,14 +2708,14 @@
       __size_(__v.__size_),
       __cap_alloc_(__v.__cap_alloc_)
 {
-    __v.__begin_ = 0;
+    __v.__begin_ = nullptr;
     __v.__size_ = 0;
     __v.__cap() = 0;
 }
 
 template <class _Allocator>
 vector<bool, _Allocator>::vector(vector&& __v, const allocator_type& __a)
-    : __begin_(0),
+    : __begin_(nullptr),
       __size_(0),
       __cap_alloc_(0, __a)
 {
@@ -3123,7 +3111,7 @@
 bool
 vector<bool, _Allocator>::__invariants() const
 {
-    if (this->__begin_ == 0)
+    if (this->__begin_ == nullptr)
     {
         if (this->__size_ != 0 || this->__cap() != 0)
             return false;