diff options
Diffstat (limited to 'system/include/libcxx/list')
-rw-r--r-- | system/include/libcxx/list | 723 |
1 files changed, 661 insertions, 62 deletions
diff --git a/system/include/libcxx/list b/system/include/libcxx/list index 900e2ec9..81258869 100644 --- a/system/include/libcxx/list +++ b/system/include/libcxx/list @@ -176,7 +176,11 @@ template <class T, class Alloc> #include <iterator> #include <algorithm> +#include <__undef_min_max> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header +#endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -209,9 +213,9 @@ struct __list_node _Tp __value_; }; -template <class _Tp, class _Alloc> class list; +template <class _Tp, class _Alloc> class _LIBCPP_VISIBLE list; template <class _Tp, class _Alloc> class __list_imp; -template <class _Tp, class _VoidPtr> class __list_const_iterator; +template <class _Tp, class _VoidPtr> class _LIBCPP_VISIBLE __list_const_iterator; template <class _Tp, class _VoidPtr> class _LIBCPP_VISIBLE __list_iterator @@ -225,8 +229,19 @@ class _LIBCPP_VISIBLE __list_iterator __node_pointer __ptr_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + explicit __list_iterator(__node_pointer __p, const void* __c) _NOEXCEPT + : __ptr_(__p) + { + __get_db()->__insert_ic(this, __c); + } +#else _LIBCPP_INLINE_VISIBILITY explicit __list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} +#endif + + template<class, class> friend class list; template<class, class> friend class __list_imp; @@ -245,25 +260,88 @@ public: typedef typename pointer_traits<pointer>::difference_type difference_type; _LIBCPP_INLINE_VISIBILITY - __list_iterator() _NOEXCEPT {} + __list_iterator() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __ptr_->__value_;} + __list_iterator(const __list_iterator& __p) + : __ptr_(__p.__ptr_) + { + __get_db()->__iterator_copy(this, &__p); + } + + _LIBCPP_INLINE_VISIBILITY + ~__list_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __list_iterator& operator=(const __list_iterator& __p) + { + if (this != &__p) + { + __get_db()->__iterator_copy(this, &__p); + __ptr_ = __p.__ptr_; + } + return *this; + } + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::iterator"); +#endif + return __ptr_->__value_; + } _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return &(operator*());} _LIBCPP_INLINE_VISIBILITY - __list_iterator& operator++() {__ptr_ = __ptr_->__next_; return *this;} + __list_iterator& operator++() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable list::iterator"); +#endif + __ptr_ = __ptr_->__next_; + return *this; + } _LIBCPP_INLINE_VISIBILITY __list_iterator operator++(int) {__list_iterator __t(*this); ++(*this); return __t;} _LIBCPP_INLINE_VISIBILITY - __list_iterator& operator--() {__ptr_ = __ptr_->__prev_; return *this;} + __list_iterator& operator--() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement non-decrementable list::iterator"); +#endif + __ptr_ = __ptr_->__prev_; + return *this; + } _LIBCPP_INLINE_VISIBILITY __list_iterator operator--(int) {__list_iterator __t(*this); --(*this); return __t;} friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __list_iterator& __x, const __list_iterator& __y) - {return __x.__ptr_ == __y.__ptr_;} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y), + "Attempted to compare non-comparable list::iterator"); +#endif + return __x.__ptr_ == __y.__ptr_; + } friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __list_iterator& __x, const __list_iterator& __y) {return !(__x == __y);} @@ -281,8 +359,17 @@ class _LIBCPP_VISIBLE __list_const_iterator __node_pointer __ptr_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + explicit __list_const_iterator(__node_pointer __p, const void* __c) _NOEXCEPT + : __ptr_(__p) + { + __get_db()->__insert_ic(this, __c); + } +#else _LIBCPP_INLINE_VISIBILITY explicit __list_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} +#endif template<class, class> friend class list; template<class, class> friend class __list_imp; @@ -300,29 +387,95 @@ public: typedef typename pointer_traits<pointer>::difference_type difference_type; _LIBCPP_INLINE_VISIBILITY - __list_const_iterator() _NOEXCEPT {} + __list_const_iterator() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } _LIBCPP_INLINE_VISIBILITY __list_const_iterator(__list_iterator<_Tp, _VoidPtr> __p) _NOEXCEPT - : __ptr_(__p.__ptr_) {} + : __ptr_(__p.__ptr_) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__iterator_copy(this, &__p); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator(const __list_const_iterator& __p) + : __ptr_(__p.__ptr_) + { + __get_db()->__iterator_copy(this, &__p); + } + + _LIBCPP_INLINE_VISIBILITY + ~__list_const_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __list_const_iterator& operator=(const __list_const_iterator& __p) + { + if (this != &__p) + { + __get_db()->__iterator_copy(this, &__p); + __ptr_ = __p.__ptr_; + } + return *this; + } +#endif // _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __ptr_->__value_;} + reference operator*() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable list::const_iterator"); +#endif + return __ptr_->__value_; + } _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return &(operator*());} _LIBCPP_INLINE_VISIBILITY - __list_const_iterator& operator++() {__ptr_ = __ptr_->__next_; return *this;} + __list_const_iterator& operator++() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable list::const_iterator"); +#endif + __ptr_ = __ptr_->__next_; + return *this; + } _LIBCPP_INLINE_VISIBILITY __list_const_iterator operator++(int) {__list_const_iterator __t(*this); ++(*this); return __t;} _LIBCPP_INLINE_VISIBILITY - __list_const_iterator& operator--() {__ptr_ = __ptr_->__prev_; return *this;} + __list_const_iterator& operator--() + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement non-decrementable list::const_iterator"); +#endif + __ptr_ = __ptr_->__prev_; + return *this; + } _LIBCPP_INLINE_VISIBILITY __list_const_iterator operator--(int) {__list_const_iterator __t(*this); --(*this); return __t;} friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __list_const_iterator& __x, const __list_const_iterator& __y) - {return __x.__ptr_ == __y.__ptr_;} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y), + "Attempted to compare non-comparable list::const_iterator"); +#endif + return __x.__ptr_ == __y.__ptr_; + } friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __list_const_iterator& __x, const __list_const_iterator& __y) {return !(__x == __y);} @@ -383,17 +536,41 @@ protected: bool empty() const _NOEXCEPT {return __sz() == 0;} _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT - {return iterator(__end_.__next_);} + iterator begin() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__end_.__next_, this); +#else + return iterator(__end_.__next_); +#endif + } _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT - {return const_iterator(__end_.__next_);} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(__end_.__next_, this); +#else + return const_iterator(__end_.__next_); +#endif + } _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT - {return iterator(static_cast<__node_pointer> (&__end_));} + iterator end() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(static_cast<__node_pointer>(&__end_), this); +#else + return iterator(static_cast<__node_pointer>(&__end_)); +#endif + } _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT - {return const_iterator(static_cast<__node_const_pointer>(&__end_));} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(static_cast<__node_const_pointer>(&__end_), this); +#else + return const_iterator(static_cast<__node_const_pointer>(&__end_)); +#endif + } void swap(__list_imp& __c) _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value || @@ -486,6 +663,9 @@ template <class _Tp, class _Alloc> __list_imp<_Tp, _Alloc>::~__list_imp() { clear(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__erase_c(this); +#endif } template <class _Tp, class _Alloc> @@ -495,17 +675,32 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT if (!empty()) { __node_allocator& __na = __node_alloc(); - iterator __f = begin(); - iterator __l = end(); - __unlink_nodes(*__f.__ptr_, *__l.__ptr_->__prev_); + __node_pointer __f = __end_.__next_; + __node_pointer __l = static_cast<__node_pointer>(&__end_); + __unlink_nodes(*__f, *__l->__prev_); __sz() = 0; while (__f != __l) { - __node& __n = *__f.__ptr_; - ++__f; + __node& __n = *__f; + __f = __f->__next_; __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_)); __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1); } +#if _LIBCPP_DEBUG_LEVEL >= 2 + __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->__ptr_ != __l) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif } } @@ -515,6 +710,10 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c) _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__node_allocator>::value) { + _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value || + this->__node_alloc() == __c.__node_alloc(), + "list::swap: Either propagate_on_container_swap must be true" + " or the allocators must compare equal"); using _VSTD::swap; __swap_alloc(__node_alloc(), __c.__node_alloc()); swap(__sz(), __c.__sz()); @@ -530,6 +729,41 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c) else __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = &static_cast<__node&>(__c.__end_); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __libcpp_db* __db = __get_db(); + __c_node* __cn1 = __db->__find_c_and_lock(this); + __c_node* __cn2 = __db->__find_c(&__c); + std::swap(__cn1->beg_, __cn2->beg_); + std::swap(__cn1->end_, __cn2->end_); + std::swap(__cn1->cap_, __cn2->cap_); + for (__i_node** __p = __cn1->end_; __p != __cn1->beg_;) + { + --__p; + const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); + if (__i->__ptr_ == static_cast<__node_pointer>(&__c.__end_)) + { + __cn2->__add(*__p); + if (--__cn1->end_ != __p) + memmove(__p, __p+1, (__cn1->end_ - __p)*sizeof(__i_node*)); + } + else + (*__p)->__c_ = __cn1; + } + for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) + { + --__p; + const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); + if (__i->__ptr_ == static_cast<__node_pointer>(&__end_)) + { + __cn1->__add(*__p); + if (--__cn2->end_ != __p) + memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); + } + else + (*__p)->__c_ = __cn2; + } + __db->unlock(); +#endif } template <class _Tp, class _Alloc = allocator<_Tp> > @@ -561,9 +795,18 @@ public: _LIBCPP_INLINE_VISIBILITY list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) - {} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + } _LIBCPP_INLINE_VISIBILITY - list(const allocator_type& __a) : base(__a) {} + list(const allocator_type& __a) : base(__a) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif + } list(size_type __n); list(size_type __n, const value_type& __x); list(size_type __n, const value_type& __x, const allocator_type& __a); @@ -649,13 +892,29 @@ public: {return const_reverse_iterator(begin());} _LIBCPP_INLINE_VISIBILITY - reference front() {return base::__end_.__next_->__value_;} + reference front() + { + _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); + return base::__end_.__next_->__value_; + } _LIBCPP_INLINE_VISIBILITY - const_reference front() const {return base::__end_.__next_->__value_;} + const_reference front() const + { + _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); + return base::__end_.__next_->__value_; + } _LIBCPP_INLINE_VISIBILITY - reference back() {return base::__end_.__prev_->__value_;} + reference back() + { + _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); + return base::__end_.__prev_->__value_; + } _LIBCPP_INLINE_VISIBILITY - const_reference back() const {return base::__end_.__prev_->__value_;} + const_reference back() const + { + _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); + return base::__end_.__prev_->__value_; + } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES void push_front(value_type&& __x); @@ -743,6 +1002,17 @@ public: void reverse() _NOEXCEPT; + bool __invariants() const; + +#if _LIBCPP_DEBUG_LEVEL >= 2 + + 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_DEBUG_LEVEL >= 2 + private: static void __link_nodes(__node& __p, __node& __f, __node& __l); iterator __iterator(size_type __n); @@ -778,6 +1048,9 @@ list<_Tp, _Alloc>::__iterator(size_type __n) template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(size_type __n) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif for (; __n > 0; --__n) #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES emplace_back(); @@ -789,6 +1062,9 @@ list<_Tp, _Alloc>::list(size_type __n) template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif for (; __n > 0; --__n) push_back(__x); } @@ -797,6 +1073,9 @@ template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif for (; __n > 0; --__n) push_back(__x); } @@ -806,6 +1085,9 @@ template <class _InpIter> list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, typename enable_if<__is_input_iterator<_InpIter>::value>::type*) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif for (; __f != __l; ++__f) push_back(*__f); } @@ -816,6 +1098,9 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a, typename enable_if<__is_input_iterator<_InpIter>::value>::type*) : base(__a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif for (; __f != __l; ++__f) push_back(*__f); } @@ -826,6 +1111,9 @@ list<_Tp, _Alloc>::list(const list& __c) __node_alloc_traits::select_on_container_copy_construction( __c.__node_alloc()))) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) push_back(*__i); } @@ -834,6 +1122,9 @@ template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(const list& __c, const allocator_type& __a) : base(__a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) push_back(*__i); } @@ -844,6 +1135,9 @@ template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a) : base(__a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), __e = __il.end(); __i != __e; ++__i) push_back(*__i); @@ -852,6 +1146,9 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& template <class _Tp, class _Alloc> list<_Tp, _Alloc>::list(initializer_list<value_type> __il) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), __e = __il.end(); __i != __e; ++__i) push_back(*__i); @@ -880,6 +1177,9 @@ list<_Tp, _Alloc>::list(list&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) : base(allocator_type(_VSTD::move(__c.__node_alloc()))) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif splice(end(), __c); } @@ -888,12 +1188,15 @@ inline _LIBCPP_INLINE_VISIBILITY list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a) : base(__a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif if (__a == __c.get_allocator()) splice(end(), __c); else { - typedef move_iterator<iterator> _I; - assign(_I(__c.begin()), _I(__c.end())); + typedef move_iterator<iterator> _Ip; + assign(_Ip(__c.begin()), _Ip(__c.end())); } } @@ -916,8 +1219,8 @@ list<_Tp, _Alloc>::__move_assign(list& __c, false_type) { if (base::__node_alloc() != __c.__node_alloc()) { - typedef move_iterator<iterator> _I; - assign(_I(__c.begin()), _I(__c.end())); + typedef move_iterator<iterator> _Ip; + assign(_Ip(__c.begin()), _Ip(__c.end())); } else __move_assign(__c, true_type()); @@ -977,9 +1280,14 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::insert(iterator, x) called with an iterator not" + " referring to this list"); +#endif __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold); @@ -991,17 +1299,28 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::insert(iterator, n, x) called with an iterator not" + " referring to this list"); + iterator __r(const_cast<__node_pointer>(__p.__ptr_), this); +#else iterator __r(const_cast<__node_pointer>(__p.__ptr_)); +#endif if (__n > 0) { size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); ++__ds; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __r = iterator(__hold.get(), this); +#else __r = iterator(__hold.get()); +#endif __hold.release(); iterator __e = __r; #ifndef _LIBCPP_NO_EXCEPTIONS @@ -1027,7 +1346,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _ __node_alloc_traits::deallocate(__na, __e.__ptr_, 1); if (__prev == 0) break; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __e = iterator(__prev, this); +#else __e = iterator(__prev); +#endif } throw; } @@ -1044,17 +1367,28 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, typename enable_if<__is_input_iterator<_InpIter>::value>::type*) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::insert(iterator, range) called with an iterator not" + " referring to this list"); + iterator __r(const_cast<__node_pointer>(__p.__ptr_), this); +#else iterator __r(const_cast<__node_pointer>(__p.__ptr_)); +#endif if (__f != __l) { size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); ++__ds; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __r = iterator(__hold.get(), this); +#else __r = iterator(__hold.get()); +#endif __hold.release(); iterator __e = __r; #ifndef _LIBCPP_NO_EXCEPTIONS @@ -1080,7 +1414,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, __node_alloc_traits::deallocate(__na, __e.__ptr_, 1); if (__prev == 0) break; +#if _LIBCPP_DEBUG_LEVEL >= 2 + __e = iterator(__prev, this); +#else __e = iterator(__prev); +#endif } throw; } @@ -1096,8 +1434,8 @@ void list<_Tp, _Alloc>::push_front(const value_type& __x) { __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); __link_nodes(*base::__end_.__next_, *__hold, *__hold); ++base::__sz(); @@ -1109,8 +1447,8 @@ void list<_Tp, _Alloc>::push_back(const value_type& __x) { __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold); ++base::__sz(); @@ -1124,8 +1462,8 @@ void list<_Tp, _Alloc>::push_front(value_type&& __x) { __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); __link_nodes(*base::__end_.__next_, *__hold, *__hold); ++base::__sz(); @@ -1137,8 +1475,8 @@ void list<_Tp, _Alloc>::push_back(value_type&& __x) { __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold); ++base::__sz(); @@ -1153,8 +1491,8 @@ void list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); __link_nodes(*base::__end_.__next_, *__hold, *__hold); ++base::__sz(); @@ -1167,8 +1505,8 @@ void list<_Tp, _Alloc>::emplace_back(_Args&&... __args) { __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); __link_nodes(static_cast<__node&>(base::__end_), *__hold, *__hold); ++base::__sz(); @@ -1181,13 +1519,17 @@ typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) { __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold); ++base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__hold.release(), this); +#else return iterator(__hold.release()); +#endif } #endif // _LIBCPP_HAS_NO_VARIADICS @@ -1196,14 +1538,23 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::insert(iterator, x) called with an iterator not" + " referring to this list"); +#endif __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); __link_nodes(const_cast<__node&>(*__p.__ptr_), *__hold, *__hold); ++base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__hold.release(), this); +#else return iterator(__hold.release()); +#endif } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -1212,10 +1563,26 @@ template <class _Tp, class _Alloc> void list<_Tp, _Alloc>::pop_front() { + _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list"); __node_allocator& __na = base::__node_alloc(); __node& __n = *base::__end_.__next_; base::__unlink_nodes(__n, __n); --base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast<iterator*>((*__p)->__i_); + if (__i->__ptr_ == &__n) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_)); __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1); } @@ -1224,10 +1591,26 @@ template <class _Tp, class _Alloc> void list<_Tp, _Alloc>::pop_back() { + _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list"); __node_allocator& __na = base::__node_alloc(); __node& __n = *base::__end_.__prev_; base::__unlink_nodes(__n, __n); --base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast<iterator*>((*__p)->__i_); + if (__i->__ptr_ == &__n) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_)); __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1); } @@ -1236,20 +1619,49 @@ template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __p) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "list::erase(iterator) called with an iterator not" + " referring to this list"); +#endif __node_allocator& __na = base::__node_alloc(); __node& __n = const_cast<__node&>(*__p.__ptr_); __node_pointer __r = __n.__next_; base::__unlink_nodes(__n, __n); --base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast<iterator*>((*__p)->__i_); + if (__i->__ptr_ == &__n) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_)); __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__r, this); +#else return iterator(__r); +#endif } template <class _Tp, class _Alloc> typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__f) == this, + "list::erase(iterator, iterator) called with an iterator not" + " referring to this list"); +#endif if (__f != __l) { __node_allocator& __na = base::__node_alloc(); @@ -1259,11 +1671,30 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) __node& __n = const_cast<__node&>(*__f.__ptr_); ++__f; --base::__sz(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast<iterator*>((*__p)->__i_); + if (__i->__ptr_ == &__n) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif __node_alloc_traits::destroy(__na, _VSTD::addressof(__n.__value_)); __node_alloc_traits::deallocate(__na, _VSTD::addressof(__n), 1); } } +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(const_cast<__node_pointer>(__l.__ptr_), this); +#else return iterator(const_cast<__node_pointer>(__l.__ptr_)); +#endif } template <class _Tp, class _Alloc> @@ -1277,12 +1708,16 @@ list<_Tp, _Alloc>::resize(size_type __n) __n -= base::__sz(); size_type __ds = 0; __node_allocator& __na = base::__node_alloc(); - typedef __allocator_destructor<__node_allocator> _D; - unique_ptr<__node, _D> __hold(__node_alloc_traits::allocate(__na, 1), _D(__na, 1)); + typedef __allocator_destructor<__node_allocator> _Dp; + unique_ptr<__node, _Dp> __hold(__node_alloc_traits::allocate(__na, 1), _Dp(__na, 1)); __hold->__prev_ = 0; __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); ++__ds; +#if _LIBCPP_DEBUG_LEVEL >= 2 + iterator __r = iterator(__hold.release(), this); +#else iterator __r = iterator(__hold.release()); +#endif iterator __e = __r; |