[libcxx] r187369 - Debug mode for unordered_multiset. The exercise spotted a few places I had missed on unordered_set, so I picked those up as well.

Howard Hinnant hhinnant at apple.com
Mon Jul 29 12:05:47 PDT 2013


Author: hhinnant
Date: Mon Jul 29 14:05:47 2013
New Revision: 187369

URL: http://llvm.org/viewvc/llvm-project?rev=187369&view=rev
Log:
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.

Added:
    libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_1.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_7.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_8.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_1.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp
Modified:
    libcxx/trunk/include/__hash_table
    libcxx/trunk/test/containers/unord/unord.multiset/bucket.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/bucket_size.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/emplace_hint.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/max_load_factor.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp
    libcxx/trunk/test/containers/unord/unord.set/bucket.pass.cpp
    libcxx/trunk/test/containers/unord/unord.set/bucket_size.pass.cpp
    libcxx/trunk/test/containers/unord/unord.set/max_load_factor.pass.cpp
    libcxx/trunk/www/debug_mode.html

Modified: libcxx/trunk/include/__hash_table
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__hash_table?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/include/__hash_table (original)
+++ libcxx/trunk/include/__hash_table Mon Jul 29 14:05:47 2013
@@ -953,7 +953,11 @@ public:
     template <class _Key>
         _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 <class _Key>
         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
 __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
 __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
 __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 <class _Tp, class _Hash, class
 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;

Modified: libcxx/trunk/test/containers/unord/unord.multiset/bucket.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/bucket.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/bucket.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multiset/bucket.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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 <unordered_set>
 #include <cassert>
 
@@ -61,4 +65,12 @@ int main()
             assert(c.bucket(i) == i % bc);
     }
 #endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_multiset<int> C;
+        C c;
+        C::size_type i = c.bucket(3);
+        assert(false);
+    }
+#endif
 }

Modified: libcxx/trunk/test/containers/unord/unord.multiset/bucket_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/bucket_size.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/bucket_size.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multiset/bucket_size.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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 <unordered_set>
 #include <cassert>
 
@@ -69,4 +73,12 @@ int main()
         assert(c.bucket_size(6) == 0);
     }
 #endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_multiset<int> C;
+        C c;
+        C::size_type i = c.bucket_size(3);
+        assert(false);
+    }
+#endif
 }

Added: libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_1.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_1.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_1.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_1.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Compare iterators from different containers with == or !=.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> C;
+    C c1;
+    C c2;
+    bool b = c1.begin() != c2.begin();
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T, min_allocator<T>> C;
+    C c1;
+    C c2;
+    bool b = c1.begin() != c2.begin();
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_7.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_7.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_7.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_7.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment iterator past end.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> 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<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.begin();
+    ++i;
+    assert(i == c.end());
+    ++i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_8.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_8.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_8.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/db_iterators_8.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> C;
+    C c(1);
+    C::iterator i = c.end();
+    T j = *i;
+    assert(false);
+    }
+#if __cplusplus >= 201103L
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T, min_allocator<T>> C;
+    C c(1);
+    C::iterator i = c.end();
+    T j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_1.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_1.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_1.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_1.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Compare local_iterators from different containers with == or !=.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> 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

Added: libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_7.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Increment local_iterator past end.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> 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<T, min_allocator<T>> C;
+    C c(1);
+    C::local_iterator i = c.begin(0);
+    ++i;
+    ++i;
+    assert(false);
+    }
+#endif
+
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/db_local_iterators_8.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Dereference non-dereferenceable iterator.
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+#include <iterator>
+#include <exception>
+#include <cstdlib>
+
+#include "../../min_allocator.h"
+
+int main()
+{
+    {
+    typedef int T;
+    typedef std::unordered_multiset<T> 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<T, min_allocator<T>> C;
+    C c(1);
+    C::local_iterator i = c.end(0);
+    T j = *i;
+    assert(false);
+    }
+#endif
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Modified: libcxx/trunk/test/containers/unord/unord.multiset/emplace_hint.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/emplace_hint.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/emplace_hint.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multiset/emplace_hint.pass.cpp Mon Jul 29 14:05:47 2013
@@ -16,6 +16,10 @@
 // template <class... Args>
 //     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 <unordered_set>
 #include <cassert>
 
@@ -62,5 +66,15 @@ int main()
         assert(*r == Emplaceable(5, 6));
     }
 #endif
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        typedef std::unordered_multiset<Emplaceable> 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
 }

Added: libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db1.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// Call erase(const_iterator position) with end()
+
+#if _LIBCPP_DEBUG2 >= 1
+
+#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : std::exit(0))
+
+#include <unordered_set>
+#include <cassert>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int>::const_iterator i = l1.end();
+    l1.erase(i);
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_db2.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// 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 <unordered_set>
+#include <cassert>
+#include <cstdlib>
+#include <exception>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int> l2(a1, a1+3);
+    std::unordered_multiset<int>::const_iterator i = l2.begin();
+    l1.erase(i);
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db1.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// 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 <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int> l2(a1, a1+3);
+    std::unordered_multiset<int>::iterator i = l1.erase(l2.cbegin(), next(l1.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db2.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// 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 <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int> l2(a1, a1+3);
+    std::unordered_multiset<int>::iterator i = l1.erase(l1.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db3.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// 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 <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int> l2(a1, a1+3);
+    std::unordered_multiset<int>::iterator i = l1.erase(l2.cbegin(), next(l2.cbegin()));
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Added: libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/erase_iter_iter_db4.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// 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 <unordered_set>
+#include <cassert>
+#include <exception>
+#include <cstdlib>
+
+int main()
+{
+    {
+    int a1[] = {1, 2, 3};
+    std::unordered_multiset<int> l1(a1, a1+3);
+    std::unordered_multiset<int>::iterator i = l1.erase(next(l1.cbegin()), l1.cbegin());
+    assert(false);
+    }
+}
+
+#else
+
+int main()
+{
+}
+
+#endif

Modified: libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_const_lvalue.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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 <unordered_set>
 #include <cassert>
 
@@ -69,4 +73,17 @@ int main()
         assert(*r == 5.5);
     }
 #endif
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        typedef std::unordered_multiset<double> 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
 }

Modified: libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multiset/insert_hint_rvalue.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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 <unordered_set>
 #include <cassert>
 
@@ -118,5 +122,17 @@ int main()
         assert(*r == 5);
     }
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        typedef std::unordered_multiset<double> 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
 }

Modified: libcxx/trunk/test/containers/unord/unord.multiset/max_load_factor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/max_load_factor.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/max_load_factor.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multiset/max_load_factor.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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 <unordered_set>
 #include <cassert>
 
@@ -55,4 +59,12 @@ int main()
         assert(c.max_load_factor() == 2.5);
     }
 #endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_multiset<int> C;
+        C c;
+        c.max_load_factor(0);
+        assert(false);
+    }
+#endif
 }

Modified: libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/assign_move.pass.cpp Mon Jul 29 14:05:47 2013
@@ -270,5 +270,17 @@ int main()
         assert(c.max_load_factor() == 1);
     }
 #endif
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        std::unordered_multiset<int> s1 = {1, 2, 3};
+        std::unordered_multiset<int>::iterator i = s1.begin();
+        int k = *i;
+        std::unordered_multiset<int> s2;
+        s2 = std::move(s1);
+        assert(*i == k);
+        s2.erase(i);
+        assert(s2.size() == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }

Modified: libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.cnstr/move.pass.cpp Mon Jul 29 14:05:47 2013
@@ -179,5 +179,16 @@ int main()
         assert(c0.empty());
     }
 #endif
+#if _LIBCPP_DEBUG2 >= 1
+    {
+        std::unordered_multiset<int> s1 = {1, 2, 3};
+        std::unordered_multiset<int>::iterator i = s1.begin();
+        int k = *i;
+        std::unordered_multiset<int> s2 = std::move(s1);
+        assert(*i == k);
+        s2.erase(i);
+        assert(s2.size() == 2);
+    }
+#endif
 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
 }

Added: libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp?rev=187369&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/unord.multiset.swap/db_swap_1.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// <unordered_set>
+
+// template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>,
+//           class Alloc = allocator<Value>>
+// 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 <unordered_set>
+#include <cassert>
+
+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<int> c1(a1, a1+sizeof(a1)/sizeof(a1[0]));
+        std::unordered_multiset<int> c2(a2, a2+sizeof(a2)/sizeof(a2[0]));
+        std::unordered_multiset<int>::iterator i1 = c1.begin();
+        std::unordered_multiset<int>::iterator i2 = c2.begin();
+        swap(c1, c2);
+        c1.erase(i2);
+        c2.erase(i1);
+        std::unordered_multiset<int>::iterator j = i1;
+        c1.erase(i1);
+        assert(false);
+    }
+#endif
+}

Modified: libcxx/trunk/test/containers/unord/unord.set/bucket.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.set/bucket.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.set/bucket.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.set/bucket.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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 <unordered_set>
 #include <cassert>
 
@@ -60,4 +64,12 @@ int main()
             assert(c.bucket(i) == i % bc);
     }
 #endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_set<int> C;
+        C c;
+        C::size_type i = c.bucket(3);
+        assert(false);
+    }
+#endif
 }

Modified: libcxx/trunk/test/containers/unord/unord.set/bucket_size.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.set/bucket_size.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.set/bucket_size.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.set/bucket_size.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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 <unordered_set>
 #include <cassert>
 
@@ -64,4 +68,12 @@ int main()
         assert(c.bucket_size(4) == 1);
     }
 #endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_set<int> C;
+        C c;
+        C::size_type i = c.bucket_size(3);
+        assert(false);
+    }
+#endif
 }

Modified: libcxx/trunk/test/containers/unord/unord.set/max_load_factor.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.set/max_load_factor.pass.cpp?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.set/max_load_factor.pass.cpp (original)
+++ libcxx/trunk/test/containers/unord/unord.set/max_load_factor.pass.cpp Mon Jul 29 14:05:47 2013
@@ -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 <unordered_set>
 #include <cassert>
 
@@ -55,4 +59,12 @@ int main()
         assert(c.max_load_factor() == 2.5);
     }
 #endif
+#if _LIBCPP_DEBUG_LEVEL >= 1
+    {
+        typedef std::unordered_set<int> C;
+        C c;
+        c.max_load_factor(-0.5f);
+        assert(false);
+    }
+#endif
 }

Modified: libcxx/trunk/www/debug_mode.html
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/debug_mode.html?rev=187369&r1=187368&r2=187369&view=diff
==============================================================================
--- libcxx/trunk/www/debug_mode.html (original)
+++ libcxx/trunk/www/debug_mode.html Mon Jul 29 14:05:47 2013
@@ -41,7 +41,7 @@ record which parts of libc++ have debug
 <code><unordered_set></code>
 </p>
 </td>
-<td><!-- ✓ --></td>
+<td> ✓ </td>
 </tr>
 
 <tr>





More information about the cfe-commits mailing list