Index: include/__debug =================================================================== --- include/__debug +++ include/__debug @@ -25,6 +25,7 @@ # include # include # include +# include #endif #if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_ASSERT) @@ -37,6 +38,8 @@ #define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m) #endif #define _LIBCPP_DEBUG_MODE(...) __VA_ARGS__ +#define _LIBCPP_DEBUG_PARAM(...) , __VA_ARGS__ +#define _LIBCPP_DEBUG_ITERATOR #endif #ifndef _LIBCPP_ASSERT @@ -48,6 +51,9 @@ #ifndef _LIBCPP_DEBUG_MODE #define _LIBCPP_DEBUG_MODE(...) ((void)0) #endif +#ifndef _LIBCPP_DEBUG_PARAM +#define _LIBCPP_DEBUG_PARAM(...) +#endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -229,6 +235,12 @@ return ::new(__mem) _C_node<_Cont>(__c, __next); } + template + _LIBCPP_INLINE_VISIBILITY + void __insert_c_helper(void *__c) { + return __insert_c(__c, &__create_C_node<_Cont>); + } + template _LIBCPP_INLINE_VISIBILITY void __insert_c(_Cont* __c) @@ -273,6 +285,104 @@ #endif // _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) + +template +struct __container_debug_base { + protected: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + __container_debug_base() noexcept { + _VSTD::__get_db()->__insert_c_helper<_Cont>(this); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + ~__container_debug_base() { + _VSTD::__get_db()->__erase_c(this); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + bool __is_valid_iterator(void* __p) _NOEXCEPT { + return std::__get_const_db()->__find_c_from_i(__p) == this; + } + + + typedef void* (_NodeToPointerFn)(void*); + + template + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + void __remove_iterator(_Iter __it, _CallBack __convert) _NOEXCEPT { + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + if (__convert((*__p)->__i_) == __it) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); + } + +#else + bool __is_valid_iterator(void* __p) _NOEXCEPT = delete; +#endif + + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + void __swap_c(void* __other) _NOEXCEPT { + _LIBCPP_DEBUG_MODE(_VSTD::__get_db()->swap(this, __other)); + ((void)__other); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + void __invalidate_all_iterators() _NOEXCEPT { + _LIBCPP_DEBUG_MODE(_VSTD::__get_db()->__invalidate_all(this)); + } + + +}; + +struct __iterator_debug_base { + protected: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + __iterator_debug_base() noexcept { + _VSTD::__get_db()->__insert_i(this); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + explicit __iterator_debug_base(const void *__c) noexcept { + _VSTD::__get_db()->__insert_ic(this, __c); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + __iterator_debug_base(__iterator_debug_base const& __other) noexcept { + _LIBCPP_DEBUG_MODE(_VSTD::__get_db()->__iterator_copy(this, &__other)); + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + __iterator_debug_base& operator=(__iterator_debug_base const& __other) noexcept { + _LIBCPP_DEBUG_MODE(if (this != &__other) { + _VSTD::__get_db()->__iterator_copy(this, &__other); + }); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + ~__iterator_debug_base() { + _VSTD::__get_db()->__erase_i(this); + } +#endif + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE + void __check_dereferenceable() const _NOEXCEPT { + _LIBCPP_DEBUG_ASSERT(std::__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable container iterator"); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_DEBUG_H Index: include/__hash_table =================================================================== --- include/__hash_table +++ include/__hash_table @@ -279,8 +279,9 @@ }; template -class _LIBCPP_TEMPLATE_VIS __hash_iterator +class _LIBCPP_TEMPLATE_VIS __hash_iterator : private __iterator_debug_base { + typedef __iterator_debug_base _DebugBase; typedef __hash_node_types<_NodePtr> _NodeTypes; typedef _NodePtr __node_pointer; typedef typename _NodeTypes::__next_pointer __next_pointer; @@ -295,53 +296,23 @@ typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { - _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY - __hash_iterator(const __hash_iterator& __i) - : __node_(__i.__node_) - { - __get_db()->__iterator_copy(this, &__i); - } - - _LIBCPP_INLINE_VISIBILITY - ~__hash_iterator() - { - __get_db()->__erase_i(this); - } - - _LIBCPP_INLINE_VISIBILITY - __hash_iterator& operator=(const __hash_iterator& __i) - { - if (this != &__i) - { - __get_db()->__iterator_copy(this, &__i); - __node_ = __i.__node_; - } - return *this; - } -#endif // _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY reference operator*() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container iterator"); + _DebugBase::__check_dereferenceable(); return __node_->__upcast()->__value_; } _LIBCPP_INLINE_VISIBILITY pointer operator->() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container iterator"); + _DebugBase::__check_dereferenceable(); return pointer_traits::pointer_to(__node_->__upcast()->__value_); } _LIBCPP_INLINE_VISIBILITY __hash_iterator& operator++() { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment non-incrementable unordered container iterator"); + _DebugBase::__check_dereferenceable(); __node_ = __node_->__next_; return *this; } @@ -364,19 +335,14 @@ {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY - __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT - : __node_(__node) - { - __get_db()->__insert_ic(this, __c); - } -#else _LIBCPP_INLINE_VISIBILITY - __hash_iterator(__next_pointer __node) _NOEXCEPT - : __node_(__node) - {} + __hash_iterator(__next_pointer __node _LIBCPP_DEBUG_PARAM(const void* __c)) _NOEXCEPT + : +#if _LIBCPP_DEBUG_LEVEL >= 2 + _DebugBase(__c), #endif + __node_(__node) + {} template friend class __hash_table; template friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; @@ -385,8 +351,11 @@ }; template -class _LIBCPP_TEMPLATE_VIS __hash_const_iterator +class _LIBCPP_TEMPLATE_VIS __hash_const_iterator : private __iterator_debug_base { + typedef __iterator_debug_base _DebugBase; + + static_assert(!is_const::element_type>::value, ""); typedef __hash_node_types<_NodePtr> _NodeTypes; typedef _NodePtr __node_pointer; @@ -405,59 +374,28 @@ _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { - _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT - : __node_(__x.__node_) - { - _LIBCPP_DEBUG_MODE(__get_db()->__iterator_copy(this, &__x)); - } - -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(const __hash_const_iterator& __i) - : __node_(__i.__node_) - { - __get_db()->__iterator_copy(this, &__i); - } - - _LIBCPP_INLINE_VISIBILITY - ~__hash_const_iterator() - { - __get_db()->__erase_i(this); - } - - _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator& operator=(const __hash_const_iterator& __i) + : _DebugBase(__x), __node_(__x.__node_) { - if (this != &__i) - { - __get_db()->__iterator_copy(this, &__i); - __node_ = __i.__node_; - } - return *this; } -#endif // _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY reference operator*() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container const_iterator"); + _DebugBase::__check_dereferenceable(); return __node_->__upcast()->__value_; } _LIBCPP_INLINE_VISIBILITY pointer operator->() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container const_iterator"); + _DebugBase::__check_dereferenceable(); return pointer_traits::pointer_to(__node_->__upcast()->__value_); } _LIBCPP_INLINE_VISIBILITY __hash_const_iterator& operator++() { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment non-incrementable unordered container const_iterator"); + _DebugBase::__check_dereferenceable(); __node_ = __node_->__next_; return *this; } @@ -480,19 +418,16 @@ {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT - : __node_(__node) + __hash_const_iterator(__next_pointer __node _LIBCPP_DEBUG_PARAM(const void* __c)) _NOEXCEPT + : +#if _LIBCPP_DEBUG_LEVEL >= 2 + _DebugBase(__c), +#endif + __node_(__node) { - __get_db()->__insert_ic(this, __c); } -#else - _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(__next_pointer __node) _NOEXCEPT - : __node_(__node) - {} -#endif + template friend class __hash_table; template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; template friend class _LIBCPP_TEMPLATE_VIS unordered_map; @@ -500,8 +435,10 @@ }; template -class _LIBCPP_TEMPLATE_VIS __hash_local_iterator +class _LIBCPP_TEMPLATE_VIS __hash_local_iterator : private __iterator_debug_base { + typedef __iterator_debug_base _DebugBase; + typedef __hash_node_types<_NodePtr> _NodeTypes; typedef _NodePtr __node_pointer; typedef typename _NodeTypes::__next_pointer __next_pointer; @@ -518,57 +455,23 @@ typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { - _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator(const __hash_local_iterator& __i) - : __node_(__i.__node_), - __bucket_(__i.__bucket_), - __bucket_count_(__i.__bucket_count_) - { - __get_db()->__iterator_copy(this, &__i); - } - - _LIBCPP_INLINE_VISIBILITY - ~__hash_local_iterator() - { - __get_db()->__erase_i(this); - } - - _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator& operator=(const __hash_local_iterator& __i) - { - if (this != &__i) - { - __get_db()->__iterator_copy(this, &__i); - __node_ = __i.__node_; - __bucket_ = __i.__bucket_; - __bucket_count_ = __i.__bucket_count_; - } - return *this; - } -#endif // _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY reference operator*() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container local_iterator"); + _DebugBase::__check_dereferenceable(); return __node_->__upcast()->__value_; } _LIBCPP_INLINE_VISIBILITY pointer operator->() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container local_iterator"); + _DebugBase::__check_dereferenceable(); return pointer_traits::pointer_to(__node_->__upcast()->__value_); } _LIBCPP_INLINE_VISIBILITY __hash_local_iterator& operator++() { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment non-incrementable unordered container local_iterator"); + _DebugBase::__check_dereferenceable(); __node_ = __node_->__next_; if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) __node_ = nullptr; @@ -593,38 +496,30 @@ {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator(__next_pointer __node, size_t __bucket, - size_t __bucket_count, const void* __c) _NOEXCEPT - : __node_(__node), - __bucket_(__bucket), - __bucket_count_(__bucket_count) - { - __get_db()->__insert_ic(this, __c); - if (__node_ != nullptr) - __node_ = __node_->__next_; - } -#else + _LIBCPP_INLINE_VISIBILITY __hash_local_iterator(__next_pointer __node, size_t __bucket, - size_t __bucket_count) _NOEXCEPT - : __node_(__node), + size_t __bucket_count _LIBCPP_DEBUG_PARAM(const void* __c)) _NOEXCEPT + : +#if _LIBCPP_DEBUG_LEVEL >= 2 + _DebugBase(__c), +#endif + __node_(__node), __bucket_(__bucket), __bucket_count_(__bucket_count) { if (__node_ != nullptr) __node_ = __node_->__next_; } -#endif template friend class __hash_table; template friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; }; template -class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator +class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator : private __iterator_debug_base { + typedef __iterator_debug_base _DebugBase; typedef __hash_node_types<_ConstNodePtr> _NodeTypes; typedef _ConstNodePtr __node_pointer; typedef typename _NodeTypes::__next_pointer __next_pointer; @@ -650,66 +545,32 @@ _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { - _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT - : __node_(__x.__node_), + : _DebugBase(__x), + __node_(__x.__node_), __bucket_(__x.__bucket_), __bucket_count_(__x.__bucket_count_) { - _LIBCPP_DEBUG_MODE(__get_db()->__iterator_copy(this, &__x)); - } - -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(const __hash_const_local_iterator& __i) - : __node_(__i.__node_), - __bucket_(__i.__bucket_), - __bucket_count_(__i.__bucket_count_) - { - __get_db()->__iterator_copy(this, &__i); - } - - _LIBCPP_INLINE_VISIBILITY - ~__hash_const_local_iterator() - { - __get_db()->__erase_i(this); - } - - _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) - { - if (this != &__i) - { - __get_db()->__iterator_copy(this, &__i); - __node_ = __i.__node_; - __bucket_ = __i.__bucket_; - __bucket_count_ = __i.__bucket_count_; - } - return *this; } -#endif // _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY reference operator*() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); + _DebugBase::__check_dereferenceable(); return __node_->__upcast()->__value_; } _LIBCPP_INLINE_VISIBILITY pointer operator->() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); + _DebugBase::__check_dereferenceable(); return pointer_traits::pointer_to(__node_->__upcast()->__value_); } _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator& operator++() { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment non-incrementable unordered container const_local_iterator"); + _DebugBase::__check_dereferenceable(); __node_ = __node_->__next_; if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) __node_ = nullptr; @@ -734,30 +595,20 @@ {return !(__x == __y);} private: -#if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator(__next_pointer __node, size_t __bucket, - size_t __bucket_count, const void* __c) _NOEXCEPT - : __node_(__node), - __bucket_(__bucket), - __bucket_count_(__bucket_count) - { - __get_db()->__insert_ic(this, __c); - if (__node_ != nullptr) - __node_ = __node_->__next_; - } -#else - _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(__next_pointer __node, size_t __bucket, - size_t __bucket_count) _NOEXCEPT - : __node_(__node), + size_t __bucket_count _LIBCPP_DEBUG_PARAM(const void* __c)) _NOEXCEPT + : +#if _LIBCPP_DEBUG_LEVEL >= 2 + _DebugBase(__c), +#endif + __node_(__node), __bucket_(__bucket), __bucket_count_(__bucket_count) { if (__node_ != nullptr) __node_ = __node_->__next_; } -#endif template friend class __hash_table; template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; }; @@ -889,7 +740,7 @@ int __diagnose_unordered_container_requirements(void*); template -class __hash_table +class __hash_table : protected __container_debug_base<__hash_table<_Tp, _Hash, _Equal, _Alloc> > { public: typedef _Tp value_type; @@ -898,6 +749,8 @@ typedef _Alloc allocator_type; private: + typedef __container_debug_base<__hash_table<_Tp, _Hash, _Equal, _Alloc> > _DebugBase; + typedef allocator_traits __alloc_traits; typedef typename __make_hash_node_types::type @@ -930,6 +783,13 @@ typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; typedef typename _NodeTypes::__next_pointer __next_pointer; + using _DebugBase::__is_valid_iterator; + + template + static __next_pointer __iter_to_node_ptr(void* __p) { + _Iter* __i = static_cast<_Iter*>(__p); + return __i->__node_; + } private: // check for sane allocator pointer rebinding semantics. Rebinding the // allocator for a new pointer type should be exactly the same as rebinding @@ -1293,11 +1153,7 @@ { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::begin(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL >= 2 - return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); -#else - return local_iterator(__bucket_list_[__n], __n, bucket_count()); -#endif + return local_iterator(__bucket_list_[__n], __n, bucket_count() _LIBCPP_DEBUG_PARAM(this)); } _LIBCPP_INLINE_VISIBILITY @@ -1306,11 +1162,7 @@ { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::end(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL >= 2 - return local_iterator(nullptr, __n, bucket_count(), this); -#else - return local_iterator(nullptr, __n, bucket_count()); -#endif + return local_iterator(nullptr, __n, bucket_count() _LIBCPP_DEBUG_PARAM(this)); } _LIBCPP_INLINE_VISIBILITY @@ -1319,11 +1171,7 @@ { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::cbegin(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL >= 2 - return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); -#else - return const_local_iterator(__bucket_list_[__n], __n, bucket_count()); -#endif + return const_local_iterator(__bucket_list_[__n], __n, bucket_count() _LIBCPP_DEBUG_PARAM(this)); } _LIBCPP_INLINE_VISIBILITY @@ -1332,11 +1180,7 @@ { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::cend(n) called with n >= bucket_count()"); -#if _LIBCPP_DEBUG_LEVEL >= 2 - return const_local_iterator(nullptr, __n, bucket_count(), this); -#else - return const_local_iterator(nullptr, __n, bucket_count()); -#endif + return const_local_iterator(nullptr, __n, bucket_count() _LIBCPP_DEBUG_PARAM(this)); } #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1497,6 +1341,7 @@ __u.__p1_.first().__next_ = nullptr; __u.size() = 0; } + _DebugBase::__swap_c(std::addressof(__u)); } template @@ -1521,6 +1366,7 @@ size() = __u.size(); __u.size() = 0; } + _DebugBase::__swap_c(std::addressof(__u)); } } @@ -1537,9 +1383,6 @@ #endif __deallocate_node(__p1_.first().__next_); -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__erase_c(this); -#endif } template @@ -1572,6 +1415,7 @@ return *this; } + template void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) @@ -1581,21 +1425,7 @@ while (__np != nullptr) { __next_pointer __next = __np->__next_; -#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((*__p)->__i_); - if (__i->__node_ == __np) - { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif + _LIBCPP_DEBUG_MODE(_DebugBase::__remove_iterator(__np, &__iter_to_node_ptr)); __node_pointer __real_np = __np->__upcast(); __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_)); __node_traits::deallocate(__na, __real_np, 1); @@ -1644,9 +1474,7 @@ __u.__p1_.first().__next_ = nullptr; __u.size() = 0; } -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->swap(this, &__u); -#endif + _DebugBase::__swap_c(std::addressof(__u)); } template @@ -1798,11 +1626,7 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL >= 2 - return iterator(__p1_.first().__next_, this); -#else - return iterator(__p1_.first().__next_); -#endif + return iterator(__p1_.first().__next_ _LIBCPP_DEBUG_PARAM(this)); } template @@ -1810,11 +1634,7 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL >= 2 - return iterator(nullptr, this); -#else - return iterator(nullptr); -#endif + return iterator(nullptr _LIBCPP_DEBUG_PARAM(this)); } template @@ -1822,11 +1642,7 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL >= 2 - return const_iterator(__p1_.first().__next_, this); -#else - return const_iterator(__p1_.first().__next_); -#endif + return const_iterator(__p1_.first().__next_ _LIBCPP_DEBUG_PARAM(this)); } template @@ -1834,11 +1650,7 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL >= 2 - return const_iterator(nullptr, this); -#else - return const_iterator(nullptr); -#endif + return const_iterator(nullptr _LIBCPP_DEBUG_PARAM(this)); } template @@ -1943,11 +1755,7 @@ __existing_node = __nd->__ptr(); __inserted = true; } -#if _LIBCPP_DEBUG_LEVEL >= 2 - return pair(iterator(__existing_node, this), __inserted); -#else - return pair(iterator(__existing_node), __inserted); -#endif + return pair(iterator(__existing_node _LIBCPP_DEBUG_PARAM(this)), __inserted); } // Prepare the container for an insertion of the value __cp_val with the hash @@ -2041,11 +1849,7 @@ __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); __node_insert_multi_perform(__cp, __pn); -#if _LIBCPP_DEBUG_LEVEL >= 2 - return iterator(__cp->__ptr(), this); -#else - return iterator(__cp->__ptr()); -#endif + return iterator(__cp->__ptr() _LIBCPP_DEBUG_PARAM(this)); } template @@ -2053,11 +1857,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( const_iterator __p, __node_pointer __cp) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__p), "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" " referring to this unordered container"); -#endif if (__p != end() && key_eq()(*__p, __cp->__value_)) { __next_pointer __np = __p.__node_; @@ -2076,11 +1878,7 @@ __cp->__next_ = __np; __pp->__next_ = static_cast<__next_pointer>(__cp); ++size(); -#if _LIBCPP_DEBUG_LEVEL >= 2 - return iterator(static_cast<__next_pointer>(__cp), this); -#else - return iterator(static_cast<__next_pointer>(__cp)); -#endif + return iterator(static_cast<__next_pointer>(__cp) _LIBCPP_DEBUG_PARAM(this)); } return __node_insert_multi(__cp); } @@ -2157,11 +1955,7 @@ __inserted = true; } __done: -#if _LIBCPP_DEBUG_LEVEL >= 2 - return pair(iterator(__nd, this), __inserted); -#else - return pair(iterator(__nd), __inserted); -#endif + return pair(iterator(__nd _LIBCPP_DEBUG_PARAM(this)), __inserted); } #ifndef _LIBCPP_CXX03_LANG @@ -2195,11 +1989,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__is_valid_iterator(&__p), "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" " referring to this unordered container"); -#endif + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); iterator __r = __node_insert_multi(__p, __h.get()); __h.release(); @@ -2223,11 +2016,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, const __container_value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__p), "unordered container::insert(const_iterator, lvalue) called with an iterator not" " referring to this unordered container"); -#endif __node_holder __h = __construct_node(__x); iterator __r = __node_insert_multi(__p, __h.get()); __h.release(); @@ -2397,9 +2188,7 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__invalidate_all(this); -#endif // _LIBCPP_DEBUG_LEVEL >= 2 + _DebugBase::__invalidate_all_iterators(); __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); __bucket_list_.reset(__nbc > 0 ? __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); @@ -2468,11 +2257,7 @@ { if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__value_, __k)) -#if _LIBCPP_DEBUG_LEVEL >= 2 - return iterator(__nd, this); -#else - return iterator(__nd); -#endif + return iterator(__nd _LIBCPP_DEBUG_PARAM(this)); } } } @@ -2499,11 +2284,7 @@ { if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__value_, __k)) -#if _LIBCPP_DEBUG_LEVEL >= 2 - return const_iterator(__nd, this); -#else - return const_iterator(__nd); -#endif + return const_iterator(__nd _LIBCPP_DEBUG_PARAM(this)); } } @@ -2584,16 +2365,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) { __next_pointer __np = __p.__node_; -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered container erase(iterator) called with an iterator not" " referring to this container"); - _LIBCPP_ASSERT(__p != end(), + _LIBCPP_DEBUG_ASSERT(__p != end(), "unordered container erase(iterator) called with a non-dereferenceable iterator"); - iterator __r(__np, this); -#else - iterator __r(__np); -#endif + iterator __r(__np _LIBCPP_DEBUG_PARAM(this)); ++__r; remove(__p); return __r; @@ -2604,25 +2382,19 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_iterator __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__first), "unodered container::erase(iterator, iterator) called with an iterator not" " referring to this unodered container"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__last), "unodered container::erase(iterator, iterator) called with an iterator not" " referring to this unodered container"); -#endif for (const_iterator __p = __first; __first != __last; __p = __first) { ++__first; erase(__p); } __next_pointer __np = __last.__node_; -#if _LIBCPP_DEBUG_LEVEL >= 2 - return iterator (__np, this); -#else - return iterator (__np); -#endif + return iterator (__np _LIBCPP_DEBUG_PARAM(this)); } template @@ -2689,21 +2461,7 @@ __pn->__next_ = __cn->__next_; __cn->__next_ = nullptr; --size(); -#if _LIBCPP_DEBUG_LEVEL >= 2 - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) - { - --__dp; - iterator* __i = static_cast((*__dp)->__i_); - if (__i->__node_ == __cn) - { - (*__dp)->__c_ = nullptr; - if (--__c->end_ != __dp) - memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif + _LIBCPP_DEBUG_MODE(_DebugBase::__remove_iterator(__cn, &__iter_to_node_ptr)); return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); } @@ -2840,9 +2598,8 @@ if (__u.size() > 0) __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = __u.__p1_.first().__ptr(); -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->swap(this, &__u); -#endif + + _DebugBase::__swap_c(std::addressof(__u)); } template Index: include/unordered_map =================================================================== --- include/unordered_map +++ include/unordered_map @@ -902,9 +902,6 @@ unordered_map() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } explicit unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); @@ -1021,13 +1018,10 @@ {return __table_.__insert_unique(__x);} iterator insert(const_iterator __p, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_DEBUG_ASSERT(__table_.__is_valid_iterator(std::addressof(__p)), "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_map"); -#else ((void)__p); -#endif return insert(__x).first; } @@ -1045,13 +1039,10 @@ {return __table_.__insert_unique(_VSTD::move(__x));} iterator insert(const_iterator __p, value_type&& __x) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_DEBUG_ASSERT(__table_.__is_valid_iterator(std::addressof(__p)), "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_map"); -#else ((void)__p); -#endif return __table_.__insert_unique(_VSTD::move(__x)).first; } @@ -1066,13 +1057,10 @@ _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, _Pp&& __x) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_DEBUG_ASSERT(__table_.__is_valid_iterator(std::addressof(__p)), "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" " referring to this unordered_map"); -#else ((void)__p); -#endif return insert(_VSTD::forward<_Pp>(__x)).first; } @@ -1085,13 +1073,10 @@ template _LIBCPP_INLINE_VISIBILITY iterator emplace_hint(const_iterator __p, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_DEBUG_ASSERT(__table_.__is_valid_iterator(std::addressof(__p)), "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" " referring to this unordered_map"); -#else ((void)__p); -#endif return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; } @@ -1120,13 +1105,11 @@ _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this, + _LIBCPP_DEBUG_ASSERT(__table_.__is_valid_iterator(std::addressof(__h)), "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" " referring to this unordered_map"); -#else ((void)__h); -#endif + return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; } @@ -1134,13 +1117,10 @@ _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this, + _LIBCPP_DEBUG_ASSERT(__table_.__is_valid_iterator(std::addressof(__h)), "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" " referring to this unordered_map"); -#else ((void)__h); -#endif return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; } @@ -1328,19 +1308,6 @@ _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) {__table_.reserve(__n);} -#if _LIBCPP_DEBUG_LEVEL >= 2 - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(&__i->__i_);} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(&__i->__i_);} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(&__i->__i_, __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(&__i->__i_, __n);} - -#endif // _LIBCPP_DEBUG_LEVEL >= 2 - private: #ifdef _LIBCPP_CXX03_LANG @@ -1353,9 +1320,6 @@ size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); } @@ -1365,9 +1329,6 @@ const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); } @@ -1377,9 +1338,6 @@ const allocator_type& __a) : __table_(typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } template @@ -1387,9 +1345,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif insert(__first, __last); } @@ -1400,9 +1355,6 @@ const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__first, __last); } @@ -1414,9 +1366,6 @@ const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__first, __last); } @@ -1426,9 +1375,6 @@ const unordered_map& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1438,9 +1384,6 @@ const unordered_map& __u, const allocator_type& __a) : __table_(__u.__table_, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1454,10 +1397,6 @@ _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); -#endif } template @@ -1465,9 +1404,6 @@ unordered_map&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -1476,19 +1412,12 @@ __u.__table_.remove((__i++).__i_)->__value_.__move()); } } -#if _LIBCPP_DEBUG_LEVEL >= 2 - else - __get_db()->swap(this, &__u); -#endif } template unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( initializer_list __il) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif insert(__il.begin(), __il.end()); } @@ -1498,9 +1427,6 @@ const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1511,9 +1437,6 @@ const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1728,9 +1651,6 @@ unordered_multimap() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); @@ -2024,21 +1944,6 @@ void rehash(size_type __n) {__table_.rehash(__n);} _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) {__table_.reserve(__n);} - -#if _LIBCPP_DEBUG_LEVEL >= 2 - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(&__i->__i_);} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(&__i->__i_);} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(&__i->__i_, __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(&__i->__i_, __n);} - -#endif // _LIBCPP_DEBUG_LEVEL >= 2 - - }; template @@ -2046,9 +1951,6 @@ size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); } @@ -2058,9 +1960,6 @@ const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); } @@ -2069,9 +1968,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif insert(__first, __last); } @@ -2082,9 +1978,6 @@ const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__first, __last); } @@ -2096,9 +1989,6 @@ const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__first, __last); } @@ -2109,9 +1999,6 @@ const allocator_type& __a) : __table_(typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } template @@ -2119,9 +2006,6 @@ const unordered_multimap& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -2131,9 +2015,6 @@ const unordered_multimap& __u, const allocator_type& __a) : __table_(__u.__table_, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -2147,10 +2028,6 @@ _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); -#endif } template @@ -2158,9 +2035,6 @@ unordered_multimap&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__a != __u.get_allocator()) { iterator __i = __u.begin(); @@ -2170,19 +2044,12 @@ __u.__table_.remove((__i++).__i_)->__value_.__move()); } } -#if _LIBCPP_DEBUG_LEVEL >= 2 - else - __get_db()->swap(this, &__u); -#endif } template unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( initializer_list __il) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif insert(__il.begin(), __il.end()); } @@ -2192,9 +2059,6 @@ const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -2205,9 +2069,6 @@ const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, typename __table::allocator_type(__a)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } Index: include/unordered_set =================================================================== --- include/unordered_set +++ include/unordered_set @@ -421,9 +421,6 @@ unordered_set() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } explicit unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); @@ -535,35 +532,27 @@ {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);} template _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL >= 2 iterator emplace_hint(const_iterator __p, _Args&&... __args) { _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not" " referring to this unordered_set"); + ((void)__p); return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; } -#else - iterator emplace_hint(const_iterator, _Args&&... __args) - {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;} -#endif _LIBCPP_INLINE_VISIBILITY pair insert(value_type&& __x) {return __table_.__insert_unique(_VSTD::move(__x));} _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL >= 2 iterator insert(const_iterator __p, value_type&& __x) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_DEBUG_ASSERT(__table_.__is_valid_iterator(std::addressof(__p)), "unordered_set::insert(const_iterator, value_type&&) called with an iterator not" " referring to this unordered_set"); + ((void)__p); return insert(_VSTD::move(__x)).first; } -#else - iterator insert(const_iterator, value_type&& __x) - {return insert(_VSTD::move(__x)).first;} -#endif _LIBCPP_INLINE_VISIBILITY void insert(initializer_list __il) {insert(__il.begin(), __il.end());} @@ -573,18 +562,15 @@ {return __table_.__insert_unique(__x);} _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL >= 2 iterator insert(const_iterator __p, const value_type& __x) { - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_DEBUG_ASSERT(__table_.__is_valid_iterator(std::addressof(__p)), "unordered_set::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_set"); + ((void)__p); return insert(__x).first; } -#else - iterator insert(const_iterator, const value_type& __x) - {return insert(__x).first;} -#endif + template _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); @@ -717,20 +703,6 @@ void rehash(size_type __n) {__table_.rehash(__n);} _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) {__table_.reserve(__n);} - -#if _LIBCPP_DEBUG_LEVEL >= 2 - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(__i);} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(__i);} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - -#endif // _LIBCPP_DEBUG_LEVEL >= 2 - }; template @@ -738,9 +710,6 @@ const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); } @@ -749,9 +718,6 @@ const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); } @@ -760,9 +726,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif insert(__first, __last); } @@ -773,9 +736,6 @@ const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__first, __last); } @@ -787,9 +747,6 @@ const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__first, __last); } @@ -800,9 +757,6 @@ const allocator_type& __a) : __table_(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } template @@ -810,9 +764,6 @@ const unordered_set& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -822,9 +773,6 @@ const unordered_set& __u, const allocator_type& __a) : __table_(__u.__table_, __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -838,10 +786,6 @@ _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); -#endif } template @@ -849,28 +793,18 @@ unordered_set&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__a != __u.get_allocator()) { iterator __i = __u.begin(); while (__u.size() != 0) __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_)); } -#if _LIBCPP_DEBUG_LEVEL >= 2 - else - __get_db()->swap(this, &__u); -#endif } template unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( initializer_list __il) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif insert(__il.begin(), __il.end()); } @@ -880,9 +814,6 @@ const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -893,9 +824,6 @@ const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1023,9 +951,6 @@ unordered_multiset() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); @@ -1288,20 +1213,6 @@ void rehash(size_type __n) {__table_.rehash(__n);} _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) {__table_.reserve(__n);} - -#if _LIBCPP_DEBUG_LEVEL >= 2 - - bool __dereferenceable(const const_iterator* __i) const - {return __table_.__dereferenceable(__i);} - bool __decrementable(const const_iterator* __i) const - {return __table_.__decrementable(__i);} - bool __addable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const - {return __table_.__addable(__i, __n);} - -#endif // _LIBCPP_DEBUG_LEVEL >= 2 - }; template @@ -1309,9 +1220,6 @@ size_type __n, const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); } @@ -1321,9 +1229,6 @@ const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); } @@ -1332,9 +1237,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif insert(__first, __last); } @@ -1345,9 +1247,6 @@ const hasher& __hf, const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__first, __last); } @@ -1359,9 +1258,6 @@ const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__first, __last); } @@ -1372,9 +1268,6 @@ const allocator_type& __a) : __table_(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } template @@ -1382,9 +1275,6 @@ const unordered_multiset& __u) : __table_(__u.__table_) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1394,9 +1284,6 @@ const unordered_multiset& __u, const allocator_type& __a) : __table_(__u.__table_, __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__u.bucket_count()); insert(__u.begin(), __u.end()); } @@ -1410,10 +1297,6 @@ _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__u); -#endif } template @@ -1421,28 +1304,18 @@ unordered_multiset&& __u, const allocator_type& __a) : __table_(_VSTD::move(__u.__table_), __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__a != __u.get_allocator()) { iterator __i = __u.begin(); while (__u.size() != 0) __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_)); } -#if _LIBCPP_DEBUG_LEVEL >= 2 - else - __get_db()->swap(this, &__u); -#endif } template unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( initializer_list __il) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif insert(__il.begin(), __il.end()); } @@ -1452,9 +1325,6 @@ const key_equal& __eql) : __table_(__hf, __eql) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } @@ -1465,9 +1335,6 @@ const key_equal& __eql, const allocator_type& __a) : __table_(__hf, __eql, __a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif __table_.rehash(__n); insert(__il.begin(), __il.end()); } Index: include/vector =================================================================== --- include/vector +++ include/vector @@ -323,7 +323,8 @@ template class __vector_base - : protected __vector_base_common + : protected __vector_base_common, + protected __container_debug_base< vector<_Tp, _Allocator> > { public: typedef _Allocator allocator_type; @@ -339,6 +340,8 @@ typedef pointer iterator; typedef const_pointer const_iterator; + typedef __container_debug_base< vector<_Tp, _Allocator> > _DebugBase; + pointer __begin_; pointer __end_; __compressed_pair __end_cap_; @@ -472,6 +475,12 @@ private: typedef __vector_base<_Tp, _Allocator> __base; typedef allocator<_Tp> __default_allocator_type; + + using __base::_DebugBase::__swap_c; + using __base::_DebugBase::__is_valid_iterator; + using __base::_DebugBase::__invalidate_all_iterators; + typedef typename __vector_base<_Tp, _Allocator>::_DebugBase _DebugBase; + public: typedef vector __self; typedef _Tp value_type; @@ -494,9 +503,6 @@ _LIBCPP_INLINE_VISIBILITY vector() _NOEXCEPT_(is_nothrow_default_constructible::value) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 @@ -506,9 +512,6 @@ #endif : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif } explicit vector(size_type __n); #if _LIBCPP_STD_VER > 11 @@ -549,9 +552,6 @@ ~vector() { __annotate_delete(); -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__erase_c(this); -#endif } vector(const vector& __x); @@ -797,7 +797,6 @@ #endif // _LIBCPP_DEBUG_LEVEL >= 2 private: - _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(pointer __new_last); void __vallocate(size_type __n); void __vdeallocate() _NOEXCEPT; @@ -1116,9 +1115,6 @@ template vector<_Tp, _Allocator>::vector(size_type __n) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__n > 0) { __vallocate(__n); @@ -1131,9 +1127,6 @@ vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__n > 0) { __vallocate(__n); @@ -1145,9 +1138,6 @@ template vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__n > 0) { __vallocate(__n); @@ -1159,9 +1149,6 @@ vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__n > 0) { __vallocate(__n); @@ -1179,9 +1166,6 @@ typename iterator_traits<_InputIterator>::reference>::value, _InputIterator>::type __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif for (; __first != __last; ++__first) __emplace_back(*__first); } @@ -1196,9 +1180,6 @@ typename iterator_traits<_InputIterator>::reference>::value>::type*) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif for (; __first != __last; ++__first) __emplace_back(*__first); } @@ -1212,9 +1193,6 @@ typename iterator_traits<_ForwardIterator>::reference>::value, _ForwardIterator>::type __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif size_type __n = static_cast(_VSTD::distance(__first, __last)); if (__n > 0) { @@ -1232,9 +1210,6 @@ typename iterator_traits<_ForwardIterator>::reference>::value>::type*) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif size_type __n = static_cast(_VSTD::distance(__first, __last)); if (__n > 0) { @@ -1247,9 +1222,6 @@ vector<_Tp, _Allocator>::vector(const vector& __x) : __base(__alloc_traits::select_on_container_copy_construction(__x.__alloc())) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif size_type __n = __x.size(); if (__n > 0) { @@ -1262,9 +1234,6 @@ vector<_Tp, _Allocator>::vector(const vector& __x, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif size_type __n = __x.size(); if (__n > 0) { @@ -1285,10 +1254,7 @@ #endif : __base(_VSTD::move(__x.__alloc())) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); - __get_db()->swap(this, &__x); -#endif + __swap_c(&__x); this->__begin_ = __x.__begin_; this->__end_ = __x.__end_; this->__end_cap() = __x.__end_cap(); @@ -1300,18 +1266,13 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__a == __x.__alloc()) { this->__begin_ = __x.__begin_; this->__end_ = __x.__end_; this->__end_cap() = __x.__end_cap(); __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr; -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->swap(this, &__x); -#endif + __swap_c(&__x); } else { @@ -1324,9 +1285,6 @@ inline _LIBCPP_INLINE_VISIBILITY vector<_Tp, _Allocator>::vector(initializer_list __il) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__il.size() > 0) { __vallocate(__il.size()); @@ -1339,9 +1297,6 @@ vector<_Tp, _Allocator>::vector(initializer_list __il, const allocator_type& __a) : __base(__a) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_c(this); -#endif if (__il.size() > 0) { __vallocate(__il.size()); @@ -1385,9 +1340,7 @@ this->__end_ = __c.__end_; this->__end_cap() = __c.__end_cap(); __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr; -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->swap(this, &__c); -#endif + __swap_c(&__c); } #endif // !_LIBCPP_CXX03_LANG @@ -1718,11 +1671,9 @@ typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __position) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__position), "vector::erase(iterator) called with an iterator not" " referring to this vector"); -#endif _LIBCPP_ASSERT(__position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator"); difference_type __ps = __position - cbegin(); @@ -1737,14 +1688,12 @@ typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__first), "vector::erase(iterator, iterator) called with an iterator not" " referring to this vector"); - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__last), "vector::erase(iterator, iterator) called with an iterator not" " referring to this vector"); -#endif _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range"); pointer __p = this->__begin_ + (__first - begin()); if (__first != __last) { @@ -1772,11 +1721,9 @@ typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__position), "vector::insert(iterator, x) called with an iterator not" " referring to this vector"); -#endif pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1813,11 +1760,9 @@ typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__position), "vector::insert(iterator, x) called with an iterator not" " referring to this vector"); -#endif pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1851,11 +1796,9 @@ typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__position), "vector::emplace(iterator, x) called with an iterator not" " referring to this vector"); -#endif pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1891,11 +1834,9 @@ typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__position), "vector::insert(iterator, n, x) called with an iterator not" " referring to this vector"); -#endif pointer __p = this->__begin_ + (__position - begin()); if (__n > 0) { @@ -1944,11 +1885,9 @@ >::type vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__position), "vector::insert(iterator, range) called with an iterator not" " referring to this vector"); -#endif difference_type __off = __position - begin(); pointer __p = this->__begin_ + __off; allocator_type& __a = this->__alloc(); @@ -2001,11 +1940,9 @@ >::type vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + _LIBCPP_DEBUG_ASSERT(__is_valid_iterator(&__position), "vector::insert(iterator, range) called with an iterator not" " referring to this vector"); -#endif pointer __p = this->__begin_ + (__position - begin()); difference_type __n = _VSTD::distance(__first, __last); if (__n > 0) @@ -2084,9 +2021,7 @@ _VSTD::swap(this->__end_cap(), __x.__end_cap()); __swap_allocator(this->__alloc(), __x.__alloc(), integral_constant()); -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->swap(this, &__x); -#endif // _LIBCPP_DEBUG_LEVEL >= 2 + __swap_c(&__x); } template @@ -2144,17 +2079,6 @@ #endif // _LIBCPP_DEBUG_LEVEL >= 2 -template -inline _LIBCPP_INLINE_VISIBILITY -void -vector<_Tp, _Allocator>::__invalidate_all_iterators() -{ -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__invalidate_all(this); -#endif // _LIBCPP_DEBUG_LEVEL >= 2 -} - - template inline _LIBCPP_INLINE_VISIBILITY void @@ -2459,7 +2383,6 @@ bool __invariants() const; private: - _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); void __vallocate(size_type __n); void __vdeallocate() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY @@ -2539,12 +2462,6 @@ friend struct _LIBCPP_TEMPLATE_VIS hash; }; -template -inline _LIBCPP_INLINE_VISIBILITY -void -vector::__invalidate_all_iterators() -{ -} // Allocate space for __n objects // throws length_error if __n > max_size() @@ -2572,7 +2489,6 @@ if (this->__begin_ != nullptr) { __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap()); - __invalidate_all_iterators(); this->__begin_ = nullptr; this->__size_ = this->__cap() = 0; } @@ -2745,7 +2661,6 @@ { if (__begin_ != nullptr) __storage_traits::deallocate(__alloc(), __begin_, __cap()); - __invalidate_all_iterators(); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2772,7 +2687,6 @@ { if (__begin_ != nullptr) __storage_traits::deallocate(__alloc(), __begin_, __cap()); - __invalidate_all_iterators(); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2847,7 +2761,6 @@ { if (__begin_ != nullptr) __storage_traits::deallocate(__alloc(), __begin_, __cap()); - __invalidate_all_iterators(); } template @@ -2991,7 +2904,6 @@ } _VSTD::fill_n(begin(), __n, __x); } - __invalidate_all_iterators(); } template @@ -3043,7 +2955,6 @@ __v.__vallocate(__n); __v.__construct_at_end(this->begin(), this->end()); swap(__v); - __invalidate_all_iterators(); } } Index: test/libcxx/debug/containers/db_unord_container_tests.pass.cpp =================================================================== --- test/libcxx/debug/containers/db_unord_container_tests.pass.cpp +++ test/libcxx/debug/containers/db_unord_container_tests.pass.cpp @@ -15,10 +15,14 @@ // UNSUPPORTED: with_system_cxx_lib // test container debugging - +#if defined(__DEPRECATED) +#undef __DEPRECATED +#endif #define _LIBCPP_DEBUG 1 #include #include +#include +#include #include #include #include "container_debug_tests.hpp" @@ -61,6 +65,12 @@ UnorderedContainerChecks< std::unordered_multiset, std::equal_to, SetAlloc>, CT_UnorderedMultiSet>::run(); + UnorderedContainerChecks< + __gnu_cxx::hash_multiset, std::equal_to, SetAlloc>, + CT_GnuHashMultiSet>::run(); + UnorderedContainerChecks< + __gnu_cxx::hash_multimap, std::equal_to, MapAlloc>, + CT_GnuHashMultiMap>::run(); } return 0; Index: test/support/container_debug_tests.hpp =================================================================== --- test/support/container_debug_tests.hpp +++ test/support/container_debug_tests.hpp @@ -59,7 +59,11 @@ CT_UnorderedMap, CT_UnorderedSet, CT_UnorderedMultiMap, - CT_UnorderedMultiSet + CT_UnorderedMultiSet, + CT_GnuHashMap, + CT_GnuHashSet, + CT_GnuHashMultiMap, + CT_GnuHashMultiSet, }; constexpr bool isSequential(ContainerType CT) { @@ -71,28 +75,41 @@ } constexpr bool isUnordered(ContainerType CT) { - return CT_UnorderedMap >= CT && CT_UnorderedMultiSet <= CT; + return CT_UnorderedMap >= CT && CT_GnuHashSet <= CT; } constexpr bool isSet(ContainerType CT) { return CT == CT_Set || CT == CT_MultiSet || CT == CT_UnorderedSet - || CT == CT_UnorderedMultiSet; + || CT == CT_UnorderedMultiSet + || CT == CT_GnuHashSet + || CT == CT_GnuHashMultiSet; } constexpr bool isMap(ContainerType CT) { return CT == CT_Map || CT == CT_MultiMap || CT == CT_UnorderedMap - || CT == CT_UnorderedMultiMap; + || CT == CT_UnorderedMultiMap + || CT == CT_GnuHashMap + || CT == CT_GnuHashMultiMap; } constexpr bool isMulti(ContainerType CT) { return CT == CT_MultiMap || CT == CT_MultiSet || CT == CT_UnorderedMultiMap - || CT == CT_UnorderedMultiSet; + || CT == CT_UnorderedMultiSet + || CT == CT_GnuHashMultiMap + || CT == CT_GnuHashMultiSet; +} + +constexpr bool isGnu(ContainerType CT) { + return CT == CT_GnuHashSet + || CT == CT_GnuHashMap + || CT == CT_GnuHashMultiSet + || CT == CT_GnuHashMultiMap; } template @@ -173,8 +190,16 @@ } } + static Container makeContainerImpl(allocator_type A) { + if constexpr (isGnu(CT)) { + return Container(5, typename Container::hasher{}, typename Container::key_equal{}, A); + } else { + return Container(A); + } + } + static Container makeContainer(int size, allocator_type A = allocator_type()) { - Container C(A); + Container C = makeContainerImpl(A); if constexpr (CT == CT_ForwardList) { for (int i = 0; i < size; ++i) C.insert_after(C.before_begin(), Helper::makeValueType(i)); @@ -239,8 +264,14 @@ static void DerefEndIterator() { CHECKPOINT("testing deref end iterator"); Container C = makeContainer(1); + const Container &CC = C; iterator i = C.begin(); - const_iterator ci = C.cbegin(); + const_iterator ci; + if constexpr (isGnu(CT)) { + ci = CC.begin(); + } else { + ci = C.cbegin(); + } (void)*i; (void)*ci; if constexpr (CT != CT_VectorBool) { i.operator->(); @@ -279,6 +310,9 @@ static void MoveInvalidatesIterators() { CHECKPOINT("copy move invalidates iterators"); + if (isGnu(CT)) { + return; // GNU containers don't have move constructors + } Container C1 = makeContainer(3); iterator i = C1.begin(); Container C2 = std::move(C1);