Initial checkin for debug mode (version 2)

llvm-svn: 139711
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: f554add54e3e9d430dd2646536fe7c475ff090d7
diff --git a/include/vector b/include/vector
index 348fe4a..d1a67ce 100644
--- a/include/vector
+++ b/include/vector
@@ -513,8 +513,18 @@
     _LIBCPP_INLINE_VISIBILITY
     vector()
         _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
-        {}
-    _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a) : __base(__a) {}
+        {
+#ifdef _LIBCPP_DEBUG2
+            __get_db()->__insert_c(this);
+#endif
+        }
+    _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a)
+        : __base(__a)
+    {
+#ifdef _LIBCPP_DEBUG2
+        __get_db()->__insert_c(this);
+#endif
+    }
     explicit vector(size_type __n);
     vector(size_type __n, const_reference __x);
     vector(size_type __n, const_reference __x, const allocator_type& __a);
@@ -538,9 +548,12 @@
     _LIBCPP_INLINE_VISIBILITY
     vector(initializer_list<value_type> __il, const allocator_type& __a);
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
-#ifdef _LIBCPP_DEBUG
+#ifdef _LIBCPP_DEBUG2
     _LIBCPP_INLINE_VISIBILITY
-    ~vector() {__invalidate_all_iterators();}
+    ~vector()
+    {
+        __get_db()->__erase_c(this);
+    }
 #endif
 
     vector(const vector& __x);
@@ -641,10 +654,26 @@
     reference       at(size_type __n);
     const_reference at(size_type __n) const;
 
-    _LIBCPP_INLINE_VISIBILITY reference       front()       {return *this->__begin_;}
-    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *this->__begin_;}
-    _LIBCPP_INLINE_VISIBILITY reference       back()        {return *(this->__end_ - 1);}
-    _LIBCPP_INLINE_VISIBILITY const_reference back()  const {return *(this->__end_ - 1);}
+    _LIBCPP_INLINE_VISIBILITY reference       front()
+    {
+        _LIBCPP_ASSERT(!empty(), "front() called for empty vector");
+        return *this->__begin_;
+    }
+    _LIBCPP_INLINE_VISIBILITY const_reference front() const
+    {
+        _LIBCPP_ASSERT(!empty(), "front() called for empty vector");
+        return *this->__begin_;
+    }
+    _LIBCPP_INLINE_VISIBILITY reference       back()
+    {
+        _LIBCPP_ASSERT(!empty(), "back() called for empty vector");
+        return *(this->__end_ - 1);
+    }
+    _LIBCPP_INLINE_VISIBILITY const_reference back()  const
+    {
+        _LIBCPP_ASSERT(!empty(), "back() called for empty vector");
+        return *(this->__end_ - 1);
+    }
 
     _LIBCPP_INLINE_VISIBILITY
     value_type*       data() _NOEXCEPT
@@ -698,7 +727,10 @@
 
     _LIBCPP_INLINE_VISIBILITY
     void clear() _NOEXCEPT
-        {__base::clear();}
+    {
+        __base::clear();
+        __invalidate_all_iterators();
+    }
 
     void resize(size_type __sz);
     void resize(size_type __sz, const_reference __x);
@@ -709,6 +741,15 @@
 
     bool __invariants() const;
 
+#ifdef _LIBCPP_DEBUG2
+
+    bool __dereferenceable(const const_iterator* __i) const;
+    bool __decrementable(const const_iterator* __i) const;
+    bool __addable(const const_iterator* __i, ptrdiff_t __n) const;
+    bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const;
+
+#endif  // _LIBCPP_DEBUG2
+
 private:
     _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
     void allocate(size_type __n);
@@ -736,6 +777,26 @@
     void __move_assign(vector& __c, true_type)
         _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
+    {
+#ifdef _LIBCPP_DEBUG2
+        __c_node* __c = __get_db()->__find_c_and_lock(this);
+        for (__i_node** __p = __c->end_; __p != __c->beg_; )
+        {
+            --__p;
+            const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_);
+            if (__i->base() > __new_last)
+            {
+                (*__p)->__c_ = nullptr;
+                if (--__c->end_ != __p)
+                    memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*));
+            }
+        }
+        __get_db()->unlock();
+#endif
+        __base::__destruct_at_end(__new_last);
+    }
 };
 
 template <class _Tp, class _Allocator>
@@ -793,7 +854,6 @@
     {
         clear();
         __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity());
-        __invalidate_all_iterators();
         this->__begin_ = this->__end_ = this->__end_cap() = 0;
     }
 }
@@ -934,6 +994,9 @@
         allocate(__n);
         __construct_at_end(__n);
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -944,6 +1007,9 @@
         allocate(__n);
         __construct_at_end(__n, __x);
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -955,6 +1021,9 @@
         allocate(__n);
         __construct_at_end(__n, __x);
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -965,6 +1034,9 @@
 {
     for (; __first != __last; ++__first)
         push_back(*__first);
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -976,6 +1048,9 @@
 {
     for (; __first != __last; ++__first)
         push_back(*__first);
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -989,6 +1064,9 @@
         allocate(__n);
         __construct_at_end(__first, __last);
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -1003,6 +1081,9 @@
         allocate(__n);
         __construct_at_end(__first, __last);
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -1015,6 +1096,9 @@
         allocate(__n);
         __construct_at_end(__x.__begin_, __x.__end_);
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -1027,6 +1111,9 @@
         allocate(__n);
         __construct_at_end(__x.__begin_, __x.__end_);
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -1041,7 +1128,10 @@
     this->__end_ = __x.__end_;
     this->__end_cap() = __x.__end_cap();
     __x.__begin_ = __x.__end_ = __x.__end_cap() = 0;
+#ifdef _LIBCPP_DEBUG2
     __x.__invalidate_all_iterators();
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -1062,6 +1152,9 @@
         typedef move_iterator<iterator> _I;
         assign(_I(__x.begin()), _I(__x.end()));
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -1075,6 +1168,9 @@
         allocate(__il.size());
         __construct_at_end(__il.begin(), __il.end());
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 template <class _Tp, class _Allocator>
@@ -1087,6 +1183,9 @@
         allocate(__il.size());
         __construct_at_end(__il.begin(), __il.end());
     }
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__insert_c(this);
+#endif
 }
 
 #endif  // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
@@ -1220,7 +1319,7 @@
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
+#ifdef _LIBCPP_DEBUG2
     return iterator(this, __p);
 #else
     return iterator(__p);
@@ -1232,7 +1331,7 @@
 typename vector<_Tp, _Allocator>::const_iterator
 vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT
 {
-#ifdef _LIBCPP_DEBUG
+#ifdef _LIBCPP_DEBUG2
     return const_iterator(this, __p);
 #else
     return const_iterator(__p);
@@ -1276,9 +1375,7 @@
 typename vector<_Tp, _Allocator>::reference
 vector<_Tp, _Allocator>::operator[](size_type __n)
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__n < size());
-#endif
+    _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
     return this->__begin_[__n];
 }
 
@@ -1287,9 +1384,7 @@
 typename vector<_Tp, _Allocator>::const_reference
 vector<_Tp, _Allocator>::operator[](size_type __n) const
 {
-#ifdef _LIBCPP_DEBUG
-    assert(__n < size());
-#endif
+    _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds");
     return this->__begin_[__n];
 }
 
@@ -1417,6 +1512,7 @@
 void
 vector<_Tp, _Allocator>::pop_back()
 {
+    _LIBCPP_ASSERT(!empty(), "vector::pop_back called for empty vector");
     this->__destruct_at_end(this->__end_ - 1);
 }
 
@@ -1425,6 +1521,9 @@
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::erase(const_iterator __position)
 {
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::erase(iterator) called with an iterator not"
+        " referring to this vector");
     pointer __p = const_cast<pointer>(&*__position);
     iterator __r = __make_iter(__p);
     this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));
@@ -1435,6 +1534,10 @@
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last)
 {
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this,
+        "vector::erase(iterator,  iterator) called with an iterator not"
+        " referring to this vector");
+    _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range");
     pointer __p = this->__begin_ + (__first - begin());
     iterator __r = __make_iter(__p);
     this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p));
@@ -1458,6 +1561,9 @@
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
 {
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, x) called with an iterator not"
+        " referring to this vector");
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
@@ -1492,6 +1598,9 @@
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
 {
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, x) called with an iterator not"
+        " referring to this vector");
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
@@ -1525,6 +1634,9 @@
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args)
 {
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::emplace(iterator, x) called with an iterator not"
+        " referring to this vector");
     pointer __p = this->__begin_ + (__position - begin());
     if (this->__end_ < this->__end_cap())
     {
@@ -1558,6 +1670,9 @@
 typename vector<_Tp, _Allocator>::iterator
 vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x)
 {
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, n, x) called with an iterator not"
+        " referring to this vector");
     pointer __p = this->__begin_ + (__position - begin());
     if (__n > 0)
     {
@@ -1601,6 +1716,9 @@
 >::type
 vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last)
 {
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, range) called with an iterator not"
+        " referring to this vector");
     difference_type __off = __position - begin();
     pointer __p = this->__begin_ + __off;
     allocator_type& __a = this->__alloc();
@@ -1648,6 +1766,9 @@
 >::type
 vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last)
 {
+    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this,
+        "vector::insert(iterator, range) called with an iterator not"
+        " referring to this vector");
     pointer __p = this->__begin_ + (__position - begin());
     difference_type __n = _VSTD::distance(__first, __last);
     if (__n > 0)
@@ -1710,13 +1831,16 @@
         _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value ||
                    __is_nothrow_swappable<allocator_type>::value)
 {
+    _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
+                   this->__alloc() == __x.__alloc(),
+                   "vector::swap: Either propagate_on_container_swap must be true"
+                   " or the allocators must compare equal");
     _VSTD::swap(this->__begin_, __x.__begin_);
     _VSTD::swap(this->__end_, __x.__end_);
     _VSTD::swap(this->__end_cap(), __x.__end_cap());
     __base::__swap_alloc(this->__alloc(), __x.__alloc());
-#ifdef _LIBCPP_DEBUG
-    iterator::swap(this, &__x);
-    const_iterator::swap(this, &__x);
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->swap(this, &__x);
 #endif  // _LIBCPP_DEBUG
 }
 
@@ -1741,16 +1865,49 @@
     return true;
 }
 
+#ifdef _LIBCPP_DEBUG2
+
 template <class _Tp, class _Allocator>
-#ifndef _LIBCPP_DEBUG
+bool
+vector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const
+{
+    return this->__begin_ <= __i->base() && __i->base() < this->__end_;
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const
+{
+    return this->__begin_ < __i->base() && __i->base() <= this->__end_;
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const_pointer __p = __i->base() + __n;
+    return this->__begin_ <= __p && __p <= this->__end_;
+}
+
+template <class _Tp, class _Allocator>
+bool
+vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const
+{
+    const_pointer __p = __i->base() + __n;
+    return this->__begin_ <= __p && __p < this->__end_;
+}
+
+#endif  // LIBCPP_DEBUG2
+
+template <class _Tp, class _Allocator>
 _LIBCPP_INLINE_VISIBILITY inline
-#endif
 void
 vector<_Tp, _Allocator>::__invalidate_all_iterators()
 {
-#ifdef _LIBCPP_DEBUG
-    iterator::__remove_all(this);
-    const_iterator::__remove_all(this);
+#ifdef _LIBCPP_DEBUG2
+    __get_db()->__invalidate_all(this);
+//     iterator::__remove_all(this);
+//     const_iterator::__remove_all(this);
 #endif  // _LIBCPP_DEBUG
 }