[libcxx] r239196 - Fix PR#23767. Add tests for iterator invalidation for deque::erase/pop_front/pop_back

Marshall Clow mclow.lists at gmail.com
Fri Jun 5 15:34:19 PDT 2015


Author: marshall
Date: Fri Jun  5 17:34:19 2015
New Revision: 239196

URL: http://llvm.org/viewvc/llvm-project?rev=239196&view=rev
Log:
Fix PR#23767. Add tests for iterator invalidation for deque::erase/pop_front/pop_back

Added:
    libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter.invalidation.pass.cpp
    libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.invalidation.pass.cpp
    libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_back.invalidation.pass.cpp
    libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_front.invalidation.pass.cpp
Modified:
    libcxx/trunk/include/deque

Modified: libcxx/trunk/include/deque
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/deque?rev=239196&r1=239195&r2=239196&view=diff
==============================================================================
--- libcxx/trunk/include/deque (original)
+++ libcxx/trunk/include/deque Fri Jun  5 17:34:19 2015
@@ -2699,7 +2699,7 @@ deque<_Tp, _Allocator>::erase(const_iter
     difference_type __pos = __f - __b;
     iterator __p = __b + __pos;
     allocator_type& __a = __base::__alloc();
-    if (__pos < (__base::size() - 1) / 2)
+    if (__pos <= (__base::size() - 1) / 2)
     {   // erase from front
         _VSTD::move_backward(__b, __p, _VSTD::next(__p));
         __alloc_traits::destroy(__a, _VSTD::addressof(*__b));
@@ -2737,7 +2737,7 @@ deque<_Tp, _Allocator>::erase(const_iter
     if (__n > 0)
     {
         allocator_type& __a = __base::__alloc();
-        if (__pos < (__base::size() - __n) / 2)
+        if (__pos <= (__base::size() - __n) / 2)
         {   // erase from front
             iterator __i = _VSTD::move_backward(__b, __p, __p + __n);
             for (; __b != __i; ++__b)

Added: libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter.invalidation.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter.invalidation.pass.cpp?rev=239196&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter.invalidation.pass.cpp (added)
+++ libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter.invalidation.pass.cpp Fri Jun  5 17:34:19 2015
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// iterator erase(const_iterator f)
+
+//  Erasing items from the beginning or the end of a deque shall not invalidate iterators
+//  to items that were not erased.
+
+#include <deque>
+#include <cassert>
+
+template <typename C>
+void del_at_start(C c)
+{
+    typename C::iterator first = c.begin();
+    typename C::iterator it1 = first + 1;
+    typename C::iterator it2 = c.end() - 1;
+    
+    c.erase (first);
+    
+    typename C::iterator it3 = c.begin();
+    typename C::iterator it4 = c.end() - 1;
+    assert(  it1 ==   it3);
+    assert( *it1 ==  *it3);
+    assert(&*it1 == &*it3);
+    assert(  it2 ==   it4);
+    assert( *it2 ==  *it4);
+    assert(&*it2 == &*it4);
+}
+
+template <typename C>
+void del_at_end(C c)
+{
+    typename C::iterator first = c.end() - 1;
+    typename C::iterator it1 = c.begin();
+    typename C::iterator it2 = first - 1;
+    
+    c.erase (first);
+
+    typename C::iterator it3 = c.begin();
+    typename C::iterator it4 = c.end() - 1;
+    assert(  it1 ==   it3);
+    assert( *it1 ==  *it3);
+    assert(&*it1 == &*it3);
+    assert(  it2 ==   it4);
+    assert( *it2 ==  *it4);
+    assert(&*it2 == &*it4);
+}
+
+int main()
+{
+    std::deque<int> queue;
+    for (int i = 0; i < 20; ++i)
+        queue.push_back(i);
+    
+    while (queue.size() > 1)
+    {
+        del_at_start(queue);
+        del_at_end(queue);
+        queue.pop_back();
+    }
+}

Added: libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.invalidation.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.invalidation.pass.cpp?rev=239196&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.invalidation.pass.cpp (added)
+++ libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/erase_iter_iter.invalidation.pass.cpp Fri Jun  5 17:34:19 2015
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// iterator erase(const_iterator f, const_iterator l)
+
+//  Erasing items from the beginning or the end of a deque shall not invalidate iterators
+//  to items that were not erased.
+
+
+#include <deque>
+#include <cstdint>
+#include <cassert>
+
+template <typename C>
+void del_at_start(C c, size_t num)
+{
+    typename C::iterator first = c.begin();
+    typename C::iterator last  = first + num;
+    typename C::iterator it1 = last;
+    typename C::iterator it2 = c.end() - 1;
+    
+    c.erase (first, last);
+    
+    typename C::iterator it3 = c.begin();
+    typename C::iterator it4 = c.end() - 1;
+    assert(  it1 ==   it3);
+    assert( *it1 ==  *it3);
+    assert(&*it1 == &*it3);
+    assert(  it2 ==   it4);
+    assert( *it2 ==  *it4);
+    assert(&*it2 == &*it4);
+}
+    
+template <typename C>
+void del_at_end(C c, size_t num)
+{
+    typename C::iterator last  = c.end();
+    typename C::iterator first = last - num;
+    typename C::iterator it1 = c.begin();
+    typename C::iterator it2 = first - 1;
+    
+    c.erase (first, last);
+
+    typename C::iterator it3 = c.begin();
+    typename C::iterator it4 = c.end() - 1;
+    assert(  it1 ==   it3);
+    assert( *it1 ==  *it3);
+    assert(&*it1 == &*it3);
+    assert(  it2 ==   it4);
+    assert( *it2 ==  *it4);
+    assert(&*it2 == &*it4);
+}
+
+
+int main()
+{
+    std::deque<int> queue;
+    for (int i = 0; i < 20; ++i)
+        queue.push_back(i);
+
+    while (queue.size() > 1)
+    {
+        for (size_t i = 1; i < queue.size(); ++i)
+        {
+            del_at_start(queue, i);
+            del_at_end  (queue, i);
+        }
+        queue.pop_back();
+    }
+}

Added: libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_back.invalidation.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_back.invalidation.pass.cpp?rev=239196&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_back.invalidation.pass.cpp (added)
+++ libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_back.invalidation.pass.cpp Fri Jun  5 17:34:19 2015
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// void pop_back()
+
+//  Erasing items from the beginning or the end of a deque shall not invalidate iterators
+//  to items that were not erased.
+
+#include <deque>
+#include <cassert>
+
+template <typename C>
+void test(C c)
+{
+    typename C::iterator it1 = c.begin();
+    typename C::iterator it2 = c.end() - 2;
+    
+    c.pop_back();
+    
+    typename C::iterator it3 = c.begin();
+    typename C::iterator it4 = c.end() - 1;
+    assert(  it1 ==   it3);
+    assert( *it1 ==  *it3);
+    assert(&*it1 == &*it3);
+    assert(  it2 ==   it4);
+    assert( *it2 ==  *it4);
+    assert(&*it2 == &*it4);
+}
+
+int main()
+{
+    std::deque<int> queue;
+    for (int i = 0; i < 20; ++i)
+        queue.push_back(i);
+    
+    while (queue.size() > 1)
+    {
+        test(queue);
+        queue.pop_back();
+    }
+}

Added: libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_front.invalidation.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_front.invalidation.pass.cpp?rev=239196&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_front.invalidation.pass.cpp (added)
+++ libcxx/trunk/test/std/containers/sequences/deque/deque.modifiers/pop_front.invalidation.pass.cpp Fri Jun  5 17:34:19 2015
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <deque>
+
+// void pop_front()
+
+//  Erasing items from the beginning or the end of a deque shall not invalidate iterators
+//  to items that were not erased.
+
+#include <deque>
+#include <cassert>
+
+template <typename C>
+void test(C c)
+{
+    typename C::iterator it1 = c.begin() + 1;
+    typename C::iterator it2 = c.end() - 1;
+    
+    c.pop_front();
+    
+    typename C::iterator it3 = c.begin();
+    typename C::iterator it4 = c.end() - 1;
+    assert(  it1 ==   it3);
+    assert( *it1 ==  *it3);
+    assert(&*it1 == &*it3);
+    assert(  it2 ==   it4);
+    assert( *it2 ==  *it4);
+    assert(&*it2 == &*it4);
+}
+
+int main()
+{
+    std::deque<int> queue;
+    for (int i = 0; i < 20; ++i)
+        queue.push_back(i);
+    
+    while (queue.size() > 1)
+    {
+        test(queue);
+        queue.pop_back();
+    }
+}





More information about the cfe-commits mailing list