From 39213641f4dbaa2f412bd6cceb57f81edcae95f9 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Tue, 23 Jul 2013 22:01:58 +0000 Subject: [PATCH] Debug mode for unordered_set. I believe this to be fairly complete for unordered_set, however it is not complete yet for unordered_multiset, unordered_map or unordered_multimap. There has been a lot of work done for these other three containers, however that work was done just to keep all of the tests passing. You can try this out with -D_LIBCPP_DEBUG2. You will have to link to a libc++.dylib that has been compiled with src/debug.cpp. So far, vector (but not vector), list, and unordered_set are treated. I hope to get the other three unordered containers up fairly quickly now that unordered_set is done. The flag _LIBCPP_DEBUG2 will eventually be changed to _LIBCPP_DEBUG, but not today. This is my second effort at getting debug mode going for libc++, and I'm not quite yet ready to throw all of the work under the first attempt away. The basic design is that all of the debug information is kept in a central database, instead of in the containers. This has been done as an attempt to have debug mode and non-debug mode be ABI compatible with each other. There are some circumstances where if you construct a container in an environment without debug mode and pass it into debug mode, the checking will get confused and let you know with a readable error message. Passing containers the other way: from debug mode out to a non-debugging mode container should be 100% safe (at least that is the goal). git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@186991 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__hash_table | 532 ++++++++++++++++-- include/unordered_map | 124 +++- include/unordered_set | 162 +++++- .../sequences/list/list.cons/move.pass.cpp | 9 + .../unord.map.cnstr/default_noexcept.pass.cpp | 4 +- .../unord.map.cnstr/dtor_noexcept.pass.cpp | 4 +- .../move_assign_noexcept.pass.cpp | 4 +- .../unord.map.cnstr/move_noexcept.pass.cpp | 4 +- .../unord.map.swap/swap_noexcept.pass.cpp | 4 +- .../default_noexcept.pass.cpp | 4 +- .../dtor_noexcept.pass.cpp | 4 +- .../move_assign_noexcept.pass.cpp | 4 +- .../move_noexcept.pass.cpp | 4 +- .../emplace_hint.pass.cpp | 4 +- .../insert_hint_const_lvalue.pass.cpp | 12 +- .../insert_hint_rvalue.pass.cpp | 16 +- .../swap_noexcept.pass.cpp | 4 +- .../unord.multiset/emplace_hint.pass.cpp | 4 +- .../insert_hint_const_lvalue.pass.cpp | 12 +- .../insert_hint_rvalue.pass.cpp | 16 +- .../unord/unord.set/db_iterators_1.pass.cpp | 54 ++ .../unord/unord.set/db_iterators_7.pass.cpp | 58 ++ .../unord/unord.set/db_iterators_8.pass.cpp | 54 ++ .../unord.set/db_local_iterators_1.pass.cpp | 43 ++ .../unord.set/db_local_iterators_7.pass.cpp | 57 ++ .../unord.set/db_local_iterators_8.pass.cpp | 54 ++ .../unord/unord.set/emplace_hint.pass.cpp | 14 + .../unord/unord.set/erase_iter_db1.pass.cpp | 38 ++ .../unord/unord.set/erase_iter_db2.pass.cpp | 41 ++ .../unord.set/erase_iter_iter_db1.pass.cpp | 40 ++ .../unord.set/erase_iter_iter_db2.pass.cpp | 40 ++ .../unord.set/erase_iter_iter_db3.pass.cpp | 40 ++ .../unord.set/erase_iter_iter_db4.pass.cpp | 39 ++ .../insert_hint_const_lvalue.pass.cpp | 17 + .../unord.set/insert_hint_rvalue.pass.cpp | 16 + .../unord.set.cnstr/assign_move.pass.cpp | 12 + .../unord.set/unord.set.cnstr/move.pass.cpp | 11 + .../unord.set.swap/db_swap_1.pass.cpp | 43 ++ 38 files changed, 1512 insertions(+), 90 deletions(-) create mode 100644 test/containers/unord/unord.set/db_iterators_1.pass.cpp create mode 100644 test/containers/unord/unord.set/db_iterators_7.pass.cpp create mode 100644 test/containers/unord/unord.set/db_iterators_8.pass.cpp create mode 100644 test/containers/unord/unord.set/db_local_iterators_1.pass.cpp create mode 100644 test/containers/unord/unord.set/db_local_iterators_7.pass.cpp create mode 100644 test/containers/unord/unord.set/db_local_iterators_8.pass.cpp create mode 100644 test/containers/unord/unord.set/erase_iter_db1.pass.cpp create mode 100644 test/containers/unord/unord.set/erase_iter_db2.pass.cpp create mode 100644 test/containers/unord/unord.set/erase_iter_iter_db1.pass.cpp create mode 100644 test/containers/unord/unord.set/erase_iter_iter_db2.pass.cpp create mode 100644 test/containers/unord/unord.set/erase_iter_iter_db3.pass.cpp create mode 100644 test/containers/unord/unord.set/erase_iter_iter_db4.pass.cpp create mode 100644 test/containers/unord/unord.set/unord.set.swap/db_swap_1.pass.cpp diff --git a/include/__hash_table b/include/__hash_table index 2b282d33..55398e4d 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -105,16 +105,67 @@ public: #endif pointer; - _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY __hash_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 __node_->__value_;} + __hash_iterator(const __hash_iterator& __i) + : __node_(__i.__node_) + { + __get_db()->__iterator_copy(this, &__i); + } + _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits::pointer_to(__node_->__value_);} + ~__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 + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container iterator"); +#endif + return __node_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container iterator"); +#endif + return pointer_traits::pointer_to(__node_->__value_); + } _LIBCPP_INLINE_VISIBILITY __hash_iterator& operator++() { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container iterator"); +#endif __node_ = __node_->__next_; return *this; } @@ -129,16 +180,31 @@ public: friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) - {return __x.__node_ == __y.__node_;} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y), + "Attempted to compare non-comparable unordered container iterator"); +#endif + return __x.__node_ == __y.__node_; + } friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) - {return __x.__node_ != __y.__node_;} + {return !(__x == __y);} private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_iterator(__node_pointer __node, const void* __c) _NOEXCEPT + : __node_(__node) + { + __get_db()->__insert_ic(this, __c); + } +#else _LIBCPP_INLINE_VISIBILITY __hash_iterator(__node_pointer __node) _NOEXCEPT : __node_(__node) {} +#endif template friend class __hash_table; template friend class _LIBCPP_TYPE_VIS __hash_const_iterator; @@ -179,20 +245,75 @@ public: __non_const_node_pointer; typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator; - _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) - {} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__iterator_copy(this, &__x); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __node_->__value_;} + __hash_const_iterator(const __hash_const_iterator& __i) + : __node_(__i.__node_) + { + __get_db()->__iterator_copy(this, &__i); + } + _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits::pointer_to(__node_->__value_);} + ~__hash_const_iterator() + { + __get_db()->__erase_i(this); + } + + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator& operator=(const __hash_const_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 + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_iterator"); +#endif + return __node_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_iterator"); +#endif + return pointer_traits::pointer_to(__node_->__value_); + } _LIBCPP_INLINE_VISIBILITY __hash_const_iterator& operator++() { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container const_iterator"); +#endif __node_ = __node_->__next_; return *this; } @@ -207,16 +328,31 @@ public: friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) - {return __x.__node_ == __y.__node_;} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y), + "Attempted to compare non-comparable unordered container const_iterator"); +#endif + return __x.__node_ == __y.__node_; + } friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) - {return __x.__node_ != __y.__node_;} + {return !(__x == __y);} private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_const_iterator(__node_pointer __node, const void* __c) _NOEXCEPT + : __node_(__node) + { + __get_db()->__insert_ic(this, __c); + } +#else _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(__node_pointer __node) _NOEXCEPT : __node_(__node) {} +#endif template friend class __hash_table; template friend class _LIBCPP_TYPE_VIS __hash_map_const_iterator; @@ -249,16 +385,71 @@ public: #endif pointer; - _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY __hash_local_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 __node_->__value_;} + __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 - pointer operator->() const {return pointer_traits::pointer_to(__node_->__value_);} + ~__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 + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container local_iterator"); +#endif + return __node_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container local_iterator"); +#endif + return pointer_traits::pointer_to(__node_->__value_); + } _LIBCPP_INLINE_VISIBILITY __hash_local_iterator& operator++() { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container local_iterator"); +#endif __node_ = __node_->__next_; if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_) __node_ = nullptr; @@ -275,12 +466,31 @@ public: friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) - {return __x.__node_ == __y.__node_;} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y), + "Attempted to compare non-comparable unordered container local_iterator"); +#endif + return __x.__node_ == __y.__node_; + } friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) - {return __x.__node_ != __y.__node_;} + {return !(__x == __y);} private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_local_iterator(__node_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(__node_pointer __node, size_t __bucket, size_t __bucket_count) _NOEXCEPT @@ -291,7 +501,7 @@ private: if (__node_ != nullptr) __node_ = __node_->__next_; } - +#endif template friend class __hash_table; template friend class _LIBCPP_TYPE_VIS __hash_const_local_iterator; template friend class _LIBCPP_TYPE_VIS __hash_map_iterator; @@ -333,22 +543,82 @@ public: #endif pointer; - _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_i(this); +#endif + } + _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_), __bucket_(__x.__bucket_), __bucket_count_(__x.__bucket_count_) - {} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__iterator_copy(this, &__x); +#endif + } + +#if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __node_->__value_;} + __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 - pointer operator->() const {return pointer_traits::pointer_to(__node_->__value_);} + ~__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 + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); +#endif + return __node_->__value_; + } + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); +#endif + return pointer_traits::pointer_to(__node_->__value_); + } _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator& operator++() { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container const_local_iterator"); +#endif __node_ = __node_->__next_; if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_) __node_ = nullptr; @@ -365,12 +635,31 @@ public: friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) - {return __x.__node_ == __y.__node_;} + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y), + "Attempted to compare non-comparable unordered container local_const_iterator"); +#endif + return __x.__node_ == __y.__node_; + } friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) - {return __x.__node_ != __y.__node_;} + {return !(__x == __y);} private: +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_INLINE_VISIBILITY + __hash_const_local_iterator(__node_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(__node_pointer __node, size_t __bucket, size_t __bucket_count) _NOEXCEPT @@ -381,7 +670,7 @@ private: if (__node_ != nullptr) __node_ = __node_->__next_; } - +#endif template friend class __hash_table; template friend class _LIBCPP_TYPE_VIS __hash_map_const_iterator; }; @@ -722,14 +1011,59 @@ public: _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT {max_load_factor() = _VSTD::max(__mlf, load_factor());} - _LIBCPP_INLINE_VISIBILITY local_iterator begin(size_type __n) - {return local_iterator(__bucket_list_[__n], __n, bucket_count());} - _LIBCPP_INLINE_VISIBILITY local_iterator end(size_type __n) - {return local_iterator(nullptr, __n, bucket_count());} - _LIBCPP_INLINE_VISIBILITY const_local_iterator cbegin(size_type __n) const - {return const_local_iterator(__bucket_list_[__n], __n, bucket_count());} - _LIBCPP_INLINE_VISIBILITY const_local_iterator cend(size_type __n) const - {return const_local_iterator(nullptr, __n, bucket_count());} + _LIBCPP_INLINE_VISIBILITY + local_iterator + begin(size_type __n) + { +#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 + } + + _LIBCPP_INLINE_VISIBILITY + local_iterator + end(size_type __n) + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return local_iterator(nullptr, __n, bucket_count(), this); +#else + return local_iterator(nullptr, __n, bucket_count()); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + const_local_iterator + cbegin(size_type __n) const + { +#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 + } + + _LIBCPP_INLINE_VISIBILITY + const_local_iterator + cend(size_type __n) const + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_local_iterator(nullptr, __n, bucket_count(), this); +#else + return const_local_iterator(nullptr, __n, bucket_count()); +#endif + } + +#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: void __rehash(size_type __n); @@ -939,6 +1273,9 @@ template __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() { __deallocate(__p1_.first().__next_); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__erase_c(this); +#endif } template @@ -980,6 +1317,21 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np) while (__np != nullptr) { __node_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 __node_traits::destroy(__na, _VSTD::addressof(__np->__value_)); __node_traits::deallocate(__na, __np, 1); __np = __next; @@ -1027,6 +1379,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( __u.__p1_.first().__next_ = nullptr; __u.size() = 0; } +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->swap(this, &__u); +#endif } template @@ -1167,7 +1522,11 @@ inline _LIBCPP_INLINE_VISIBILITY 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 } template @@ -1175,7 +1534,11 @@ inline _LIBCPP_INLINE_VISIBILITY 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 } template @@ -1183,7 +1546,11 @@ inline _LIBCPP_INLINE_VISIBILITY 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 } template @@ -1191,7 +1558,11 @@ inline _LIBCPP_INLINE_VISIBILITY 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 } template @@ -1264,7 +1635,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ __inserted = true; } __done: +#if _LIBCPP_DEBUG_LEVEL >= 2 + return pair(iterator(__ndptr, this), __inserted); +#else return pair(iterator(__ndptr), __inserted); +#endif } template @@ -1321,7 +1696,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c } } ++size(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__cp, this); +#else return iterator(__cp); +#endif } template @@ -1347,7 +1726,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( __cp->__next_ = __np; __pp->__next_ = __cp; ++size(); +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__cp, this); +#else return iterator(__cp); +#endif } return __node_insert_multi(__cp); } @@ -1408,7 +1791,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x) __inserted = true; } __done: +#if _LIBCPP_DEBUG_LEVEL >= 2 + return pair(iterator(__nd, this), __inserted); +#else return pair(iterator(__nd), __inserted); +#endif } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -1543,6 +1930,9 @@ template 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 __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); __bucket_list_.reset(__nbc > 0 ? __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); @@ -1608,7 +1998,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) __nd = __nd->__next_) { if (key_eq()(__nd->__value_, __k)) +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator(__nd, this); +#else return iterator(__nd); +#endif } } } @@ -1633,7 +2027,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const __nd = __nd->__next_) { if (key_eq()(__nd->__value_, __k)) +#if _LIBCPP_DEBUG_LEVEL >= 2 + return const_iterator(__nd, this); +#else return const_iterator(__nd); +#endif } } @@ -1710,7 +2108,16 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) { __node_pointer __np = __p.__node_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_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(), + "unordered container erase(iterator) called with a non-dereferenceable iterator"); + iterator __r(__np, this); +#else iterator __r(__np); +#endif ++__r; remove(__p); return __r; @@ -1721,13 +2128,25 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __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, + "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, + "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); } __node_pointer __np = __last.__node_; +#if _LIBCPP_DEBUG_LEVEL >= 2 + return iterator (__np, this); +#else return iterator (__np); +#endif } template @@ -1793,6 +2212,21 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT __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** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + iterator* __i = static_cast((*__p)->__i_); + if (__i->__node_ == __cn) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif return __node_holder(__cn, _Dp(__node_alloc(), true)); } @@ -1921,6 +2355,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) if (__u.size() > 0) __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash_, __u.bucket_count())] = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__u.__p1_.first())); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->swap(this, &__u); +#endif } template @@ -1950,6 +2387,37 @@ swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_DEBUG_LEVEL >= 2 + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const +{ + return __i->__node_ != nullptr; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const +{ + return false; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const +{ + return false; +} + +template +bool +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const +{ + return false; +} + +#endif // _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP__HASH_TABLE diff --git a/include/unordered_map b/include/unordered_map index 78e63075..55db2f5f 100644 --- a/include/unordered_map +++ b/include/unordered_map @@ -624,6 +624,8 @@ public: typedef pair __nc_value_type; typedef value_type& reference; typedef const value_type& const_reference; + static_assert((is_same::value), + "Invalid allocator::value_type"); private: #if __cplusplus >= 201103L @@ -706,7 +708,11 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_map() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - {} // = default; + { +#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()); unordered_map(size_type __n, const hasher& __hf, @@ -905,6 +911,19 @@ public: _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: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __node_holder __construct_node(); @@ -925,6 +944,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( 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); } @@ -934,6 +956,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const allocator_type& __a) : __table_(__hf, __eql, __a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif __table_.rehash(__n); } @@ -943,6 +968,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const allocator_type& __a) : __table_(__a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif } template @@ -950,6 +978,9 @@ template 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); } @@ -960,6 +991,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( 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); } @@ -971,6 +1005,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( 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); } @@ -980,6 +1017,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( 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()); } @@ -989,6 +1029,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const unordered_map& __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()); } @@ -1002,6 +1045,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif } template @@ -1009,6 +1055,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( unordered_map&& __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(); @@ -1027,6 +1076,9 @@ 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()); } @@ -1036,6 +1088,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( 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()); } @@ -1046,6 +1101,9 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( 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()); } @@ -1286,6 +1344,8 @@ public: typedef pair __nc_value_type; typedef value_type& reference; typedef const value_type& const_reference; + static_assert((is_same::value), + "Invalid allocator::value_type"); private: #if __cplusplus >= 201103L @@ -1366,7 +1426,11 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_multimap() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - {} // = default; + { +#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()); unordered_multimap(size_type __n, const hasher& __hf, @@ -1556,6 +1620,19 @@ public: _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: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __node_holder __construct_node(); @@ -1574,6 +1651,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( 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); } @@ -1583,6 +1663,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const allocator_type& __a) : __table_(__hf, __eql, __a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif __table_.rehash(__n); } @@ -1591,6 +1674,9 @@ template 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); } @@ -1601,6 +1687,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( 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); } @@ -1612,6 +1701,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( 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); } @@ -1622,6 +1714,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const allocator_type& __a) : __table_(__a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif } template @@ -1629,6 +1724,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( 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()); } @@ -1638,6 +1736,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const unordered_multimap& __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()); } @@ -1651,6 +1752,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_VSTD::move(__u.__table_)) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif } template @@ -1658,15 +1762,18 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( unordered_multimap&& __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++).__i_)->__value_) ); -} + } } } @@ -1678,6 +1785,9 @@ 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()); } @@ -1687,6 +1797,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( 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()); } @@ -1697,6 +1810,9 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( 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()); } diff --git a/include/unordered_set b/include/unordered_set index 119251dc..8be36df6 100644 --- a/include/unordered_set +++ b/include/unordered_set @@ -324,6 +324,8 @@ public: typedef _Alloc allocator_type; typedef value_type& reference; typedef const value_type& const_reference; + static_assert((is_same::value), + "Invalid allocator::value_type"); private: typedef __hash_table __table; @@ -344,7 +346,11 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_set() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - {} // = default; + { +#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()); unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, @@ -422,8 +428,18 @@ public: {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"); + 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 #endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) _LIBCPP_INLINE_VISIBILITY pair insert(const value_type& __x) @@ -434,12 +450,32 @@ public: {return __table_.__insert_unique(_VSTD::move(__x));} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _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, + "unordered_set::insert(const_iterator, const value_type&) called with an iterator not" + " referring to this unordered_set"); + return insert(__x).first; + } +#else iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;} +#endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _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, + "unordered_set::insert(const_iterator, value_type&&) called with an iterator not" + " referring to this unordered_set"); + return insert(_VSTD::move(__x)).first; + } +#else iterator insert(const_iterator, value_type&& __x) {return insert(_VSTD::move(__x)).first;} +#endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template void insert(_InputIterator __first, _InputIterator __last); @@ -515,6 +551,20 @@ public: 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 @@ -522,6 +572,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(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); } @@ -530,6 +583,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, 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); } @@ -538,6 +594,9 @@ template 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); } @@ -548,6 +607,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( 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); } @@ -559,6 +621,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( 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); } @@ -569,6 +634,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const allocator_type& __a) : __table_(__a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif } template @@ -576,6 +644,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( 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()); } @@ -585,6 +656,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( 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()); } @@ -598,6 +672,10 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( _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 @@ -605,12 +683,19 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( 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 } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -621,6 +706,9 @@ 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()); } @@ -630,6 +718,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( 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()); } @@ -640,6 +731,9 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( 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()); } @@ -736,6 +830,8 @@ public: typedef _Alloc allocator_type; typedef value_type& reference; typedef const value_type& const_reference; + static_assert((is_same::value), + "Invalid allocator::value_type"); private: typedef __hash_table __table; @@ -756,7 +852,11 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_multiset() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) - {} // = default + { +#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()); unordered_multiset(size_type __n, const hasher& __hf, @@ -925,6 +1025,20 @@ public: 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 @@ -932,6 +1046,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( 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); } @@ -941,6 +1058,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__hf, __eql, __a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif __table_.rehash(__n); } @@ -949,6 +1069,9 @@ template 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); } @@ -959,6 +1082,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( 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); } @@ -970,6 +1096,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( 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); } @@ -980,6 +1109,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__a) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif } template @@ -987,6 +1119,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( 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()); } @@ -996,6 +1131,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( 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()); } @@ -1009,6 +1147,10 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( _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 @@ -1016,12 +1158,19 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( 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 } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -1032,6 +1181,9 @@ 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()); } @@ -1041,6 +1193,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( 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()); } @@ -1051,6 +1206,9 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( 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()); } diff --git a/test/containers/sequences/list/list.cons/move.pass.cpp b/test/containers/sequences/list/list.cons/move.pass.cpp index 37542025..2811a3e7 100644 --- a/test/containers/sequences/list/list.cons/move.pass.cpp +++ b/test/containers/sequences/list/list.cons/move.pass.cpp @@ -61,5 +61,14 @@ int main() assert(l2.get_allocator() == lo.get_allocator()); } #endif +#if _LIBCPP_DEBUG2 >= 1 + { + std::list l1 = {1, 2, 3}; + std::list::iterator i = l1.begin(); + std::list l2 = std::move(l1); + assert(*l2.erase(i) == 2); + assert(l2.size() == 2); + } +#endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp index 7f426fdb..ebf8e137 100644 --- a/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp +++ b/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp @@ -49,12 +49,12 @@ int main() } { typedef std::unordered_map, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; static_assert(std::is_nothrow_default_constructible::value, ""); } { typedef std::unordered_map, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; static_assert(!std::is_nothrow_default_constructible::value, ""); } { diff --git a/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp index e605b66e..5d2e4c4a 100644 --- a/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp +++ b/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp @@ -46,12 +46,12 @@ int main() } { typedef std::unordered_map, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; static_assert(std::is_nothrow_destructible::value, ""); } { typedef std::unordered_map, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; static_assert(std::is_nothrow_destructible::value, ""); } { diff --git a/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp index 758a7868..27174b32 100644 --- a/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp +++ b/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp @@ -48,12 +48,12 @@ int main() } { typedef std::unordered_map, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; static_assert(!std::is_nothrow_move_assignable::value, ""); } { typedef std::unordered_map, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; static_assert(std::is_nothrow_move_assignable::value, ""); } { diff --git a/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp index 952c478b..3a97097a 100644 --- a/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp +++ b/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp @@ -45,12 +45,12 @@ int main() } { typedef std::unordered_map, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; static_assert(std::is_nothrow_move_constructible::value, ""); } { typedef std::unordered_map, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; static_assert(std::is_nothrow_move_constructible::value, ""); } { diff --git a/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp index 3786f18f..579b6d55 100644 --- a/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp +++ b/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp @@ -48,13 +48,13 @@ int main() } { typedef std::unordered_map, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; C c1, c2; static_assert(noexcept(swap(c1, c2)), ""); } { typedef std::unordered_map, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; C c1, c2; static_assert(noexcept(swap(c1, c2)), ""); } diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp index cbf7a0da..cc8bb721 100644 --- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp +++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp @@ -49,12 +49,12 @@ int main() } { typedef std::unordered_multimap, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; static_assert(std::is_nothrow_default_constructible::value, ""); } { typedef std::unordered_multimap, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; static_assert(!std::is_nothrow_default_constructible::value, ""); } { diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp index 2833f7e8..f6c8551b 100644 --- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp +++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp @@ -46,12 +46,12 @@ int main() } { typedef std::unordered_multimap, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; static_assert(std::is_nothrow_destructible::value, ""); } { typedef std::unordered_multimap, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; static_assert(std::is_nothrow_destructible::value, ""); } { diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp index d53c5cdb..ee69b33a 100644 --- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp +++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp @@ -48,12 +48,12 @@ int main() } { typedef std::unordered_multimap, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; static_assert(!std::is_nothrow_move_assignable::value, ""); } { typedef std::unordered_multimap, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; static_assert(std::is_nothrow_move_assignable::value, ""); } { diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp index b6e7c4de..7eb5f320 100644 --- a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp +++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp @@ -45,12 +45,12 @@ int main() } { typedef std::unordered_multimap, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; static_assert(std::is_nothrow_move_constructible::value, ""); } { typedef std::unordered_multimap, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; static_assert(std::is_nothrow_move_constructible::value, ""); } { diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp index bad1ee28..0c3aff61 100644 --- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp +++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/emplace_hint.pass.cpp @@ -36,7 +36,7 @@ int main() assert(r->first == 3); assert(r->second == Emplaceable()); - r = c.emplace_hint(e, std::pair(3, Emplaceable(5, 6))); + r = c.emplace_hint(c.end(), std::pair(3, Emplaceable(5, 6))); assert(c.size() == 2); assert(r->first == 3); assert(r->second == Emplaceable(5, 6)); @@ -68,7 +68,7 @@ int main() assert(r->first == 3); assert(r->second == Emplaceable()); - r = c.emplace_hint(e, std::pair(3, Emplaceable(5, 6))); + r = c.emplace_hint(c.end(), std::pair(3, Emplaceable(5, 6))); assert(c.size() == 2); assert(r->first == 3); assert(r->second == Emplaceable(5, 6)); diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp index 9e3f1280..e5d5b536 100644 --- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp +++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_const_lvalue.pass.cpp @@ -33,17 +33,17 @@ int main() assert(r->first == 3.5); assert(r->second == 3); - r = c.insert(e, P(3.5, 4)); + r = c.insert(c.end(), P(3.5, 4)); assert(c.size() == 2); assert(r->first == 3.5); assert(r->second == 4); - r = c.insert(e, P(4.5, 4)); + r = c.insert(c.end(), P(4.5, 4)); assert(c.size() == 3); assert(r->first == 4.5); assert(r->second == 4); - r = c.insert(e, P(5.5, 4)); + r = c.insert(c.end(), P(5.5, 4)); assert(c.size() == 4); assert(r->first == 5.5); assert(r->second == 4); @@ -61,17 +61,17 @@ int main() assert(r->first == 3.5); assert(r->second == 3); - r = c.insert(e, P(3.5, 4)); + r = c.insert(c.end(), P(3.5, 4)); assert(c.size() == 2); assert(r->first == 3.5); assert(r->second == 4); - r = c.insert(e, P(4.5, 4)); + r = c.insert(c.end(), P(4.5, 4)); assert(c.size() == 3); assert(r->first == 4.5); assert(r->second == 4); - r = c.insert(e, P(5.5, 4)); + r = c.insert(c.end(), P(5.5, 4)); assert(c.size() == 4); assert(r->first == 5.5); assert(r->second == 4); diff --git a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp index c8dd38d5..7be2811e 100644 --- a/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp +++ b/test/containers/unord/unord.multimap/unord.multimap.modifiers/insert_hint_rvalue.pass.cpp @@ -41,12 +41,12 @@ int main() assert(r->first == 3.5); assert(r->second == 4); - r = c.insert(e, P(4.5, 4)); + r = c.insert(c.end(), P(4.5, 4)); assert(c.size() == 3); assert(r->first == 4.5); assert(r->second == 4); - r = c.insert(e, P(5.5, 4)); + r = c.insert(c.end(), P(5.5, 4)); assert(c.size() == 4); assert(r->first == 5.5); assert(r->second == 4); @@ -68,12 +68,12 @@ int main() assert(r->first == 3); assert(r->second == 4); - r = c.insert(e, P(4, 4)); + r = c.insert(c.end(), P(4, 4)); assert(c.size() == 3); assert(r->first == 4); assert(r->second == 4); - r = c.insert(e, P(5, 4)); + r = c.insert(c.end(), P(5, 4)); assert(c.size() == 4); assert(r->first == 5); assert(r->second == 4); @@ -97,12 +97,12 @@ int main() assert(r->first == 3.5); assert(r->second == 4); - r = c.insert(e, P(4.5, 4)); + r = c.insert(c.end(), P(4.5, 4)); assert(c.size() == 3); assert(r->first == 4.5); assert(r->second == 4); - r = c.insert(e, P(5.5, 4)); + r = c.insert(c.end(), P(5.5, 4)); assert(c.size() == 4); assert(r->first == 5.5); assert(r->second == 4); @@ -125,12 +125,12 @@ int main() assert(r->first == 3); assert(r->second == 4); - r = c.insert(e, P(4, 4)); + r = c.insert(c.end(), P(4, 4)); assert(c.size() == 3); assert(r->first == 4); assert(r->second == 4); - r = c.insert(e, P(5, 4)); + r = c.insert(c.end(), P(5, 4)); assert(c.size() == 4); assert(r->first == 5); assert(r->second == 4); diff --git a/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp index 2560919b..227a700f 100644 --- a/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp +++ b/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp @@ -48,13 +48,13 @@ int main() } { typedef std::unordered_multimap, - std::equal_to, test_allocator> C; + std::equal_to, test_allocator>> C; C c1, c2; static_assert(noexcept(swap(c1, c2)), ""); } { typedef std::unordered_multimap, - std::equal_to, other_allocator> C; + std::equal_to, other_allocator>> C; C c1, c2; static_assert(noexcept(swap(c1, c2)), ""); } diff --git a/test/containers/unord/unord.multiset/emplace_hint.pass.cpp b/test/containers/unord/unord.multiset/emplace_hint.pass.cpp index 25a3b759..aff6ba7c 100644 --- a/test/containers/unord/unord.multiset/emplace_hint.pass.cpp +++ b/test/containers/unord/unord.multiset/emplace_hint.pass.cpp @@ -34,7 +34,7 @@ int main() assert(c.size() == 1); assert(*r == Emplaceable()); - r = c.emplace_hint(e, Emplaceable(5, 6)); + r = c.emplace_hint(c.end(), Emplaceable(5, 6)); assert(c.size() == 2); assert(*r == Emplaceable(5, 6)); @@ -53,7 +53,7 @@ int main() assert(c.size() == 1); assert(*r == Emplaceable()); - r = c.emplace_hint(e, Emplaceable(5, 6)); + r = c.emplace_hint(c.end(), Emplaceable(5, 6)); assert(c.size() == 2); assert(*r == Emplaceable(5, 6)); diff --git a/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp b/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp index 02b8375f..b15a5f09 100644 --- a/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp +++ b/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp @@ -32,15 +32,15 @@ int main() assert(c.size() == 1); assert(*r == 3.5); - r = c.insert(e, P(3.5)); + r = c.insert(c.end(), P(3.5)); assert(c.size() == 2); assert(*r == 3.5); - r = c.insert(e, P(4.5)); + r = c.insert(c.end(), P(4.5)); assert(c.size() == 3); assert(*r == 4.5); - r = c.insert(e, P(5.5)); + r = c.insert(c.end(), P(5.5)); assert(c.size() == 4); assert(*r == 5.5); } @@ -56,15 +56,15 @@ int main() assert(c.size() == 1); assert(*r == 3.5); - r = c.insert(e, P(3.5)); + r = c.insert(c.end(), P(3.5)); assert(c.size() == 2); assert(*r == 3.5); - r = c.insert(e, P(4.5)); + r = c.insert(c.end(), P(4.5)); assert(c.size() == 3); assert(*r == 4.5); - r = c.insert(e, P(5.5)); + r = c.insert(c.end(), P(5.5)); assert(c.size() == 4); assert(*r == 5.5); } diff --git a/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp b/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp index 590baa05..019bd077 100644 --- a/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp +++ b/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp @@ -37,11 +37,11 @@ int main() assert(c.size() == 2); assert(*r == 3.5); - r = c.insert(e, P(4.5)); + r = c.insert(c.end(), P(4.5)); assert(c.size() == 3); assert(*r == 4.5); - r = c.insert(e, P(5.5)); + r = c.insert(c.end(), P(5.5)); assert(c.size() == 4); assert(*r == 5.5); } @@ -60,11 +60,11 @@ int main() assert(c.size() == 2); assert(*r == 3); - r = c.insert(e, P(4)); + r = c.insert(c.end(), P(4)); assert(c.size() == 3); assert(*r == 4); - r = c.insert(e, P(5)); + r = c.insert(c.end(), P(5)); assert(c.size() == 4); assert(*r == 5); } @@ -85,11 +85,11 @@ int main() assert(c.size() == 2); assert(*r == 3.5); - r = c.insert(e, P(4.5)); + r = c.insert(c.end(), P(4.5)); assert(c.size() == 3); assert(*r == 4.5); - r = c.insert(e, P(5.5)); + r = c.insert(c.end(), P(5.5)); assert(c.size() == 4); assert(*r == 5.5); } @@ -109,11 +109,11 @@ int main() assert(c.size() == 2); assert(*r == 3); - r = c.insert(e, P(4)); + r = c.insert(c.end(), P(4)); assert(c.size() == 3); assert(*r == 4); - r = c.insert(e, P(5)); + r = c.insert(c.end(), P(5)); assert(c.size() == 4); assert(*r == 5); } diff --git a/test/containers/unord/unord.set/db_iterators_1.pass.cpp b/test/containers/unord/unord.set/db_iterators_1.pass.cpp new file mode 100644 index 00000000..2835c010 --- /dev/null +++ b/test/containers/unord/unord.set/db_iterators_1.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Compare iterators from different containers with == or !=. + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "../../min_allocator.h" + +int main() +{ + { + typedef int T; + typedef std::unordered_set C; + C c1; + C c2; + bool b = c1.begin() != c2.begin(); + assert(false); + } +#if __cplusplus >= 201103L + { + typedef int T; + typedef std::unordered_set> C; + C c1; + C c2; + bool b = c1.begin() != c2.begin(); + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/db_iterators_7.pass.cpp b/test/containers/unord/unord.set/db_iterators_7.pass.cpp new file mode 100644 index 00000000..978ee088 --- /dev/null +++ b/test/containers/unord/unord.set/db_iterators_7.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Increment iterator past end. + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "../../min_allocator.h" + +int main() +{ + { + typedef int T; + typedef std::unordered_set C; + C c(1); + C::iterator i = c.begin(); + ++i; + assert(i == c.end()); + ++i; + assert(false); + } +#if __cplusplus >= 201103L + { + typedef int T; + typedef std::unordered_set> C; + C c(1); + C::iterator i = c.begin(); + ++i; + assert(i == c.end()); + ++i; + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/db_iterators_8.pass.cpp b/test/containers/unord/unord.set/db_iterators_8.pass.cpp new file mode 100644 index 00000000..26411871 --- /dev/null +++ b/test/containers/unord/unord.set/db_iterators_8.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Dereference non-dereferenceable iterator. + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "../../min_allocator.h" + +int main() +{ + { + typedef int T; + typedef std::unordered_set C; + C c(1); + C::iterator i = c.end(); + T j = *i; + assert(false); + } +#if __cplusplus >= 201103L + { + typedef int T; + typedef std::unordered_set> C; + C c(1); + C::iterator i = c.end(); + T j = *i; + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/db_local_iterators_1.pass.cpp b/test/containers/unord/unord.set/db_local_iterators_1.pass.cpp new file mode 100644 index 00000000..f432471e --- /dev/null +++ b/test/containers/unord/unord.set/db_local_iterators_1.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Compare local_iterators from different containers with == or !=. + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include + +int main() +{ + { + typedef int T; + typedef std::unordered_set C; + C c1; + c1.insert(1); + C c2; + c2.insert(1); + C::local_iterator i = c1.begin(c1.bucket(1)); + C::local_iterator j = c2.begin(c2.bucket(1)); + assert(i != j); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/db_local_iterators_7.pass.cpp b/test/containers/unord/unord.set/db_local_iterators_7.pass.cpp new file mode 100644 index 00000000..87fdf1b2 --- /dev/null +++ b/test/containers/unord/unord.set/db_local_iterators_7.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Increment local_iterator past end. + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "../../min_allocator.h" + +int main() +{ + { + typedef int T; + typedef std::unordered_set C; + C c(1); + C::local_iterator i = c.begin(0); + ++i; + ++i; + assert(false); + } +#if __cplusplus >= 201103L + { + typedef int T; + typedef std::unordered_set> C; + C c(1); + C::local_iterator i = c.begin(0); + ++i; + ++i; + assert(false); + } +#endif + +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/db_local_iterators_8.pass.cpp b/test/containers/unord/unord.set/db_local_iterators_8.pass.cpp new file mode 100644 index 00000000..33d7be05 --- /dev/null +++ b/test/containers/unord/unord.set/db_local_iterators_8.pass.cpp @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Dereference non-dereferenceable iterator. + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include +#include + +#include "../../min_allocator.h" + +int main() +{ + { + typedef int T; + typedef std::unordered_set C; + C c(1); + C::local_iterator i = c.end(0); + T j = *i; + assert(false); + } +#if __cplusplus >= 201103L + { + typedef int T; + typedef std::unordered_set> C; + C c(1); + C::local_iterator i = c.end(0); + T j = *i; + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/emplace_hint.pass.cpp b/test/containers/unord/unord.set/emplace_hint.pass.cpp index de00ebee..b988669c 100644 --- a/test/containers/unord/unord.set/emplace_hint.pass.cpp +++ b/test/containers/unord/unord.set/emplace_hint.pass.cpp @@ -16,6 +16,10 @@ // template // iterator emplace_hint(const_iterator p, Args&&... args); +#if _LIBCPP_DEBUG2 >= 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + #include #include @@ -62,5 +66,15 @@ int main() assert(*r == Emplaceable(5, 6)); } #endif +#if _LIBCPP_DEBUG2 >= 1 + { + typedef std::unordered_set C; + typedef C::iterator R; + C c1; + C c2; + R r = c1.emplace_hint(c2.begin(), 5, 6); + assert(false); + } +#endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/containers/unord/unord.set/erase_iter_db1.pass.cpp b/test/containers/unord/unord.set/erase_iter_db1.pass.cpp new file mode 100644 index 00000000..4cecf26d --- /dev/null +++ b/test/containers/unord/unord.set/erase_iter_db1.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Call erase(const_iterator position) with end() + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include + +int main() +{ + { + int a1[] = {1, 2, 3}; + std::unordered_set l1(a1, a1+3); + std::unordered_set::const_iterator i = l1.end(); + l1.erase(i); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/erase_iter_db2.pass.cpp b/test/containers/unord/unord.set/erase_iter_db2.pass.cpp new file mode 100644 index 00000000..0f6a102e --- /dev/null +++ b/test/containers/unord/unord.set/erase_iter_db2.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Call erase(const_iterator position) with iterator from another container + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include + +int main() +{ + { + int a1[] = {1, 2, 3}; + std::unordered_set l1(a1, a1+3); + std::unordered_set l2(a1, a1+3); + std::unordered_set::const_iterator i = l2.begin(); + l1.erase(i); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/erase_iter_iter_db1.pass.cpp b/test/containers/unord/unord.set/erase_iter_iter_db1.pass.cpp new file mode 100644 index 00000000..ce0eb0bb --- /dev/null +++ b/test/containers/unord/unord.set/erase_iter_iter_db1.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Call erase(const_iterator first, const_iterator last); with first iterator from another container + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include + +int main() +{ + { + int a1[] = {1, 2, 3}; + std::unordered_set l1(a1, a1+3); + std::unordered_set l2(a1, a1+3); + std::unordered_set::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin())); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/erase_iter_iter_db2.pass.cpp b/test/containers/unord/unord.set/erase_iter_iter_db2.pass.cpp new file mode 100644 index 00000000..6b06bb41 --- /dev/null +++ b/test/containers/unord/unord.set/erase_iter_iter_db2.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Call erase(const_iterator first, const_iterator last); with second iterator from another container + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include + +int main() +{ + { + int a1[] = {1, 2, 3}; + std::unordered_set l1(a1, a1+3); + std::unordered_set l2(a1, a1+3); + std::unordered_set::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin())); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/erase_iter_iter_db3.pass.cpp b/test/containers/unord/unord.set/erase_iter_iter_db3.pass.cpp new file mode 100644 index 00000000..33902f10 --- /dev/null +++ b/test/containers/unord/unord.set/erase_iter_iter_db3.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Call erase(const_iterator first, const_iterator last); with both iterators from another container + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include + +int main() +{ + { + int a1[] = {1, 2, 3}; + std::unordered_set l1(a1, a1+3); + std::unordered_set l2(a1, a1+3); + std::unordered_set::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin())); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/erase_iter_iter_db4.pass.cpp b/test/containers/unord/unord.set/erase_iter_iter_db4.pass.cpp new file mode 100644 index 00000000..79fc846c --- /dev/null +++ b/test/containers/unord/unord.set/erase_iter_iter_db4.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// Call erase(const_iterator first, const_iterator last); with a bad range + +#if _LIBCPP_DEBUG2 >= 1 + +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) + +#include +#include +#include +#include + +int main() +{ + { + int a1[] = {1, 2, 3}; + std::unordered_set l1(a1, a1+3); + std::unordered_set::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin()); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/test/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp b/test/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp index cbc212aa..46c32fa2 100644 --- a/test/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp +++ b/test/containers/unord/unord.set/insert_hint_const_lvalue.pass.cpp @@ -15,6 +15,10 @@ // iterator insert(const_iterator p, const value_type& x); +#if _LIBCPP_DEBUG2 >= 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + #include #include @@ -69,4 +73,17 @@ int main() assert(*r == 5.5); } #endif +#if _LIBCPP_DEBUG2 >= 1 + { + typedef std::unordered_set C; + typedef C::iterator R; + typedef C::value_type P; + C c; + C c2; + C::const_iterator e = c2.end(); + P v(3.5); + R r = c.insert(e, v); + assert(false); + } +#endif } diff --git a/test/containers/unord/unord.set/insert_hint_rvalue.pass.cpp b/test/containers/unord/unord.set/insert_hint_rvalue.pass.cpp index 8d7e5ba7..e5ba2c0a 100644 --- a/test/containers/unord/unord.set/insert_hint_rvalue.pass.cpp +++ b/test/containers/unord/unord.set/insert_hint_rvalue.pass.cpp @@ -15,6 +15,10 @@ // iterator insert(const_iterator p, value_type&& x); +#if _LIBCPP_DEBUG2 >= 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + #include #include @@ -118,5 +122,17 @@ int main() assert(*r == 5); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if _LIBCPP_DEBUG2 >= 1 + { + typedef std::unordered_set C; + typedef C::iterator R; + typedef C::value_type P; + C c; + C c2; + C::const_iterator e = c2.end(); + R r = c.insert(e, P(3.5)); + assert(false); + } +#endif #endif } diff --git a/test/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp b/test/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp index 8dab47b8..02e1b976 100644 --- a/test/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp +++ b/test/containers/unord/unord.set/unord.set.cnstr/assign_move.pass.cpp @@ -209,5 +209,17 @@ int main() assert(c.max_load_factor() == 1); } #endif +#if _LIBCPP_DEBUG2 >= 1 + { + std::unordered_set s1 = {1, 2, 3}; + std::unordered_set::iterator i = s1.begin(); + int k = *i; + std::unordered_set s2; + s2 = std::move(s1); + assert(*i == k); + s2.erase(i); + assert(s2.size() == 2); + } +#endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/containers/unord/unord.set/unord.set.cnstr/move.pass.cpp b/test/containers/unord/unord.set/unord.set.cnstr/move.pass.cpp index 5c75a3e8..4967679e 100644 --- a/test/containers/unord/unord.set/unord.set.cnstr/move.pass.cpp +++ b/test/containers/unord/unord.set/unord.set.cnstr/move.pass.cpp @@ -179,5 +179,16 @@ int main() assert(c0.empty()); } #endif +#if _LIBCPP_DEBUG2 >= 1 + { + std::unordered_set s1 = {1, 2, 3}; + std::unordered_set::iterator i = s1.begin(); + int k = *i; + std::unordered_set s2 = std::move(s1); + assert(*i == k); + s2.erase(i); + assert(s2.size() == 2); + } +#endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/test/containers/unord/unord.set/unord.set.swap/db_swap_1.pass.cpp b/test/containers/unord/unord.set/unord.set.swap/db_swap_1.pass.cpp new file mode 100644 index 00000000..829fc95b --- /dev/null +++ b/test/containers/unord/unord.set/unord.set.swap/db_swap_1.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template , class Pred = equal_to, +// class Alloc = allocator> +// class unordered_set + +// void swap(unordered_set& x, unordered_set& y); + +#if _LIBCPP_DEBUG2 >= 1 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + +#include +#include + +int main() +{ +#if _LIBCPP_DEBUG2 >= 1 + { + int a1[] = {1, 3, 7, 9, 10}; + int a2[] = {0, 2, 4, 5, 6, 8, 11}; + std::unordered_set c1(a1, a1+sizeof(a1)/sizeof(a1[0])); + std::unordered_set c2(a2, a2+sizeof(a2)/sizeof(a2[0])); + std::unordered_set::iterator i1 = c1.begin(); + std::unordered_set::iterator i2 = c2.begin(); + swap(c1, c2); + c1.erase(i2); + c2.erase(i1); + std::unordered_set::iterator j = i1; + c1.erase(i1); + assert(false); + } +#endif +}