From: Howard Hinnant Date: Mon, 29 Jul 2013 19:05:47 +0000 (+0000) Subject: Debug mode for unordered_multiset. The exercise spotted a few places I had missed... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e5c13decbe4c6109719cd6cdd68140576cb4671f;p=platform%2Fupstream%2Fllvm.git Debug mode for unordered_multiset. The exercise spotted a few places I had missed on unordered_set, so I picked those up as well. There are actually two debug modes: 1. -D_LIBCPP_DEBUG2 or -D_LIBCPP_DEBUG2=1 This is a relatively expensive debug mode, but very thorough. This is normally what you want to debug with, but may turn O(1) operations into O(N) operations. 2. -D_LIBCPP_DEBUG2=0 This is "debug lite." Only preconditions that can be checked with O(1) expense are checked. For example range checking on an indexing operation. But not iterator validity. llvm-svn: 187369 --- diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 55398e4..0f72294 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -953,7 +953,11 @@ public: template _LIBCPP_INLINE_VISIBILITY size_type bucket(const _Key& __k) const - {return __constrain_hash(hash_function()(__k), bucket_count());} + { + _LIBCPP_ASSERT(bucket_count() > 0, + "unordered container::bucket(key) called when bucket_count() == 0"); + return __constrain_hash(hash_function()(__k), bucket_count()); + } template iterator find(const _Key& __x); @@ -1009,12 +1013,18 @@ public: return __bc != 0 ? (float)size() / __bc : 0.f; } _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT - {max_load_factor() = _VSTD::max(__mlf, load_factor());} + { + _LIBCPP_ASSERT(__mlf > 0, + "unordered container::max_load_factor(lf) called with lf <= 0"); + max_load_factor() = _VSTD::max(__mlf, load_factor()); + } _LIBCPP_INLINE_VISIBILITY local_iterator begin(size_type __n) { + _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 @@ -1026,6 +1036,8 @@ public: local_iterator end(size_type __n) { + _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 @@ -1037,6 +1049,8 @@ public: const_local_iterator cbegin(size_type __n) const { + _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 @@ -1048,6 +1062,8 @@ public: const_local_iterator cend(size_type __n) const { + _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 @@ -1830,6 +1846,11 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __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, + "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(); @@ -1871,6 +1892,11 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, _Pp&& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered container::insert(const_iterator, rvalue) called with an iterator not" + " referring to this unordered container"); +#endif __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); iterator __r = __node_insert_multi(__p, __h.get()); __h.release(); @@ -1894,6 +1920,11 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, const value_type& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "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(); @@ -2364,6 +2395,8 @@ template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const { + _LIBCPP_ASSERT(__n < bucket_count(), + "unordered container::bucket_size(n) called with n >= bucket_count()"); __node_const_pointer __np = __bucket_list_[__n]; size_type __bc = bucket_count(); size_type __r = 0; diff --git a/libcxx/test/containers/unord/unord.multiset/bucket.pass.cpp b/libcxx/test/containers/unord/unord.multiset/bucket.pass.cpp index 99a72ab..e75a133 100644 --- a/libcxx/test/containers/unord/unord.multiset/bucket.pass.cpp +++ b/libcxx/test/containers/unord/unord.multiset/bucket.pass.cpp @@ -15,6 +15,10 @@ // size_type bucket(const key_type& __k) const; +#ifdef _LIBCPP_DEBUG2 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + #include #include @@ -61,4 +65,12 @@ int main() assert(c.bucket(i) == i % bc); } #endif +#if _LIBCPP_DEBUG_LEVEL >= 1 + { + typedef std::unordered_multiset C; + C c; + C::size_type i = c.bucket(3); + assert(false); + } +#endif } diff --git a/libcxx/test/containers/unord/unord.multiset/bucket_size.pass.cpp b/libcxx/test/containers/unord/unord.multiset/bucket_size.pass.cpp index 0f2977d..3e71087 100644 --- a/libcxx/test/containers/unord/unord.multiset/bucket_size.pass.cpp +++ b/libcxx/test/containers/unord/unord.multiset/bucket_size.pass.cpp @@ -15,6 +15,10 @@ // size_type bucket_size(size_type n) const +#ifdef _LIBCPP_DEBUG2 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + #include #include @@ -69,4 +73,12 @@ int main() assert(c.bucket_size(6) == 0); } #endif +#if _LIBCPP_DEBUG_LEVEL >= 1 + { + typedef std::unordered_multiset C; + C c; + C::size_type i = c.bucket_size(3); + assert(false); + } +#endif } diff --git a/libcxx/test/containers/unord/unord.multiset/db_iterators_1.pass.cpp b/libcxx/test/containers/unord/unord.multiset/db_iterators_1.pass.cpp new file mode 100644 index 0000000..cddf771 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset C; + C c1; + C c2; + bool b = c1.begin() != c2.begin(); + assert(false); + } +#if __cplusplus >= 201103L + { + typedef int T; + typedef std::unordered_multiset> C; + C c1; + C c2; + bool b = c1.begin() != c2.begin(); + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/db_iterators_7.pass.cpp b/libcxx/test/containers/unord/unord.multiset/db_iterators_7.pass.cpp new file mode 100644 index 0000000..f6ed6c7 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset 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_multiset> 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/libcxx/test/containers/unord/unord.multiset/db_iterators_8.pass.cpp b/libcxx/test/containers/unord/unord.multiset/db_iterators_8.pass.cpp new file mode 100644 index 0000000..289fa5e --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset C; + C c(1); + C::iterator i = c.end(); + T j = *i; + assert(false); + } +#if __cplusplus >= 201103L + { + typedef int T; + typedef std::unordered_multiset> C; + C c(1); + C::iterator i = c.end(); + T j = *i; + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/db_local_iterators_1.pass.cpp b/libcxx/test/containers/unord/unord.multiset/db_local_iterators_1.pass.cpp new file mode 100644 index 0000000..39e3c69 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset 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/libcxx/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp b/libcxx/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp new file mode 100644 index 0000000..b2f4017 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset C; + C c(1); + C::local_iterator i = c.begin(0); + ++i; + ++i; + assert(false); + } +#if __cplusplus >= 201103L + { + typedef int T; + typedef std::unordered_multiset> C; + C c(1); + C::local_iterator i = c.begin(0); + ++i; + ++i; + assert(false); + } +#endif + +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp b/libcxx/test/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp new file mode 100644 index 0000000..47afad4 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset 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_multiset> C; + C c(1); + C::local_iterator i = c.end(0); + T j = *i; + assert(false); + } +#endif +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/emplace_hint.pass.cpp b/libcxx/test/containers/unord/unord.multiset/emplace_hint.pass.cpp index aff6ba7..e153169 100644 --- a/libcxx/test/containers/unord/unord.multiset/emplace_hint.pass.cpp +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset 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/libcxx/test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp b/libcxx/test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp new file mode 100644 index 0000000..beab0bb --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset l1(a1, a1+3); + std::unordered_multiset::const_iterator i = l1.end(); + l1.erase(i); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp b/libcxx/test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp new file mode 100644 index 0000000..a58e79a --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset l1(a1, a1+3); + std::unordered_multiset l2(a1, a1+3); + std::unordered_multiset::const_iterator i = l2.begin(); + l1.erase(i); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp b/libcxx/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp new file mode 100644 index 0000000..de8bca8 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset l1(a1, a1+3); + std::unordered_multiset l2(a1, a1+3); + std::unordered_multiset::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin())); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp b/libcxx/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp new file mode 100644 index 0000000..8abded2 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset l1(a1, a1+3); + std::unordered_multiset l2(a1, a1+3); + std::unordered_multiset::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin())); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp b/libcxx/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp new file mode 100644 index 0000000..626def4 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset l1(a1, a1+3); + std::unordered_multiset l2(a1, a1+3); + std::unordered_multiset::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin())); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp b/libcxx/test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp new file mode 100644 index 0000000..4840234 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset l1(a1, a1+3); + std::unordered_multiset::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin()); + assert(false); + } +} + +#else + +int main() +{ +} + +#endif diff --git a/libcxx/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp b/libcxx/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp index b15a5f0..c27b5c2 100644 --- a/libcxx/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset 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/libcxx/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp b/libcxx/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp index 019bd07..23ac231 100644 --- a/libcxx/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp +++ b/libcxx/test/containers/unord/unord.multiset/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_multiset 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/libcxx/test/containers/unord/unord.multiset/max_load_factor.pass.cpp b/libcxx/test/containers/unord/unord.multiset/max_load_factor.pass.cpp index f2beb8f..72413be 100644 --- a/libcxx/test/containers/unord/unord.multiset/max_load_factor.pass.cpp +++ b/libcxx/test/containers/unord/unord.multiset/max_load_factor.pass.cpp @@ -16,6 +16,10 @@ // float max_load_factor() const; // void max_load_factor(float mlf); +#ifdef _LIBCPP_DEBUG2 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + #include #include @@ -55,4 +59,12 @@ int main() assert(c.max_load_factor() == 2.5); } #endif +#if _LIBCPP_DEBUG_LEVEL >= 1 + { + typedef std::unordered_multiset C; + C c; + c.max_load_factor(0); + assert(false); + } +#endif } diff --git a/libcxx/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp b/libcxx/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp index 292f50ffd..c77846a 100644 --- a/libcxx/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp +++ b/libcxx/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp @@ -270,5 +270,17 @@ int main() assert(c.max_load_factor() == 1); } #endif +#if _LIBCPP_DEBUG2 >= 1 + { + std::unordered_multiset s1 = {1, 2, 3}; + std::unordered_multiset::iterator i = s1.begin(); + int k = *i; + std::unordered_multiset 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/libcxx/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp b/libcxx/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp index e24d8f3..92c5781 100644 --- a/libcxx/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp +++ b/libcxx/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp @@ -179,5 +179,16 @@ int main() assert(c0.empty()); } #endif +#if _LIBCPP_DEBUG2 >= 1 + { + std::unordered_multiset s1 = {1, 2, 3}; + std::unordered_multiset::iterator i = s1.begin(); + int k = *i; + std::unordered_multiset s2 = std::move(s1); + assert(*i == k); + s2.erase(i); + assert(s2.size() == 2); + } +#endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES } diff --git a/libcxx/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp b/libcxx/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp new file mode 100644 index 0000000..d75d227 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/unord.multiset.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_multiset + +// void swap(unordered_multiset& x, unordered_multiset& 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_multiset c1(a1, a1+sizeof(a1)/sizeof(a1[0])); + std::unordered_multiset c2(a2, a2+sizeof(a2)/sizeof(a2[0])); + std::unordered_multiset::iterator i1 = c1.begin(); + std::unordered_multiset::iterator i2 = c2.begin(); + swap(c1, c2); + c1.erase(i2); + c2.erase(i1); + std::unordered_multiset::iterator j = i1; + c1.erase(i1); + assert(false); + } +#endif +} diff --git a/libcxx/test/containers/unord/unord.set/bucket.pass.cpp b/libcxx/test/containers/unord/unord.set/bucket.pass.cpp index 25f6581..a07ef25 100644 --- a/libcxx/test/containers/unord/unord.set/bucket.pass.cpp +++ b/libcxx/test/containers/unord/unord.set/bucket.pass.cpp @@ -15,6 +15,10 @@ // size_type bucket(const key_type& __k) const; +#ifdef _LIBCPP_DEBUG2 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + #include #include @@ -60,4 +64,12 @@ int main() assert(c.bucket(i) == i % bc); } #endif +#if _LIBCPP_DEBUG_LEVEL >= 1 + { + typedef std::unordered_set C; + C c; + C::size_type i = c.bucket(3); + assert(false); + } +#endif } diff --git a/libcxx/test/containers/unord/unord.set/bucket_size.pass.cpp b/libcxx/test/containers/unord/unord.set/bucket_size.pass.cpp index aecb2585..13b8257 100644 --- a/libcxx/test/containers/unord/unord.set/bucket_size.pass.cpp +++ b/libcxx/test/containers/unord/unord.set/bucket_size.pass.cpp @@ -15,6 +15,10 @@ // size_type bucket_size(size_type n) const +#ifdef _LIBCPP_DEBUG2 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + #include #include @@ -64,4 +68,12 @@ int main() assert(c.bucket_size(4) == 1); } #endif +#if _LIBCPP_DEBUG_LEVEL >= 1 + { + typedef std::unordered_set C; + C c; + C::size_type i = c.bucket_size(3); + assert(false); + } +#endif } diff --git a/libcxx/test/containers/unord/unord.set/max_load_factor.pass.cpp b/libcxx/test/containers/unord/unord.set/max_load_factor.pass.cpp index db7e784..44cf865 100644 --- a/libcxx/test/containers/unord/unord.set/max_load_factor.pass.cpp +++ b/libcxx/test/containers/unord/unord.set/max_load_factor.pass.cpp @@ -16,6 +16,10 @@ // float max_load_factor() const; // void max_load_factor(float mlf); +#ifdef _LIBCPP_DEBUG2 +#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0)) +#endif + #include #include @@ -55,4 +59,12 @@ int main() assert(c.max_load_factor() == 2.5); } #endif +#if _LIBCPP_DEBUG_LEVEL >= 1 + { + typedef std::unordered_set C; + C c; + c.max_load_factor(-0.5f); + assert(false); + } +#endif } diff --git a/libcxx/www/debug_mode.html b/libcxx/www/debug_mode.html index ba491b3..6a77317 100644 --- a/libcxx/www/debug_mode.html +++ b/libcxx/www/debug_mode.html @@ -41,7 +41,7 @@ record which parts of libc++ have debug mode support. <unordered_set>

- + ✓