<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 16, 2014 at 1:38 PM, Marshall Clow <span dir="ltr"><<a href="mailto:mclow.lists@gmail.com" target="_blank">mclow.lists@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: marshall<br>
Date: Tue Sep 16 15:38:11 2014<br>
New Revision: 217902<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=217902&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=217902&view=rev</a><br>
Log:<br>
Create a 'comma_iterator' class that overloads operator, and asserts when it's called. Add tests to mismatch to make sure it can't be blindsided by such an evil iterator. More tests for other algorithms forthcoming. Thanks to STL for pointing this out at CppCon and Yakov Galka for opening LWG issue #2133<br></blockquote><div><br></div><div>Could it use "= delete" to make this test fail at compile-time?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Modified:<br>
    libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp<br>
    libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp<br>
    libcxx/trunk/test/support/test_iterators.h<br>
<br>
Modified: libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp?rev=217902&r1=217901&r2=217902&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp?rev=217902&r1=217901&r2=217902&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp (original)<br>
+++ libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp Tue Sep 16 15:38:11 2014<br>
@@ -36,6 +36,14 @@ int main()<br>
                             input_iterator<const int*>(ia+3),<br>
                             input_iterator<const int*>(ib+3))));<br>
<br>
+    assert(std::mismatch(comma_iterator<const int*>(ia),<br>
+                         comma_iterator<const int*>(ia + sa),<br>
+                         comma_iterator<const int*>(ib)) ==<br>
+                         (std::pair<comma_iterator<const int*>,<br>
+                                    comma_iterator<const int*> >(<br>
+                            comma_iterator<const int*>(ia+3),<br>
+                            comma_iterator<const int*>(ib+3))));<br>
+<br>
 #ifdef HAS_FOUR_ITERATOR_VERSION<br>
     assert(std::mismatch(input_iterator<const int*>(ia),<br>
                          input_iterator<const int*>(ia + sa),<br>
<br>
Modified: libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp?rev=217902&r1=217901&r2=217902&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp?rev=217902&r1=217901&r2=217902&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp (original)<br>
+++ libcxx/trunk/test/algorithms/alg.nonmodifying/mismatch/mismatch_pred.pass.cpp Tue Sep 16 15:38:11 2014<br>
@@ -39,6 +39,14 @@ int main()<br>
                                     input_iterator<const int*> >(<br>
                             input_iterator<const int*>(ia+3),<br>
                             input_iterator<const int*>(ib+3))));<br>
+    assert(std::mismatch(comma_iterator<const int*>(ia),<br>
+                         comma_iterator<const int*>(ia + sa),<br>
+                         comma_iterator<const int*>(ib),<br>
+                         std::equal_to<int>()) ==<br>
+                         (std::pair<comma_iterator<const int*>,<br>
+                                    comma_iterator<const int*> >(<br>
+                            comma_iterator<const int*>(ia+3),<br>
+                            comma_iterator<const int*>(ib+3))));<br>
 #ifdef HAS_FOUR_ITERATOR_VERSION<br>
     assert(std::mismatch(input_iterator<const int*>(ia),<br>
                          input_iterator<const int*>(ia + sa),<br>
<br>
Modified: libcxx/trunk/test/support/test_iterators.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/test_iterators.h?rev=217902&r1=217901&r2=217902&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/support/test_iterators.h?rev=217902&r1=217901&r2=217902&view=diff</a><br>
==============================================================================<br>
--- libcxx/trunk/test/support/test_iterators.h (original)<br>
+++ libcxx/trunk/test/support/test_iterators.h Tue Sep 16 15:38:11 2014<br>
@@ -284,6 +284,108 @@ operator-(const random_access_iterator<T<br>
     return x.base() - y.base();<br>
 }<br>
<br>
+template <class It><br>
+class comma_iterator<br>
+{<br>
+    It it_;<br>
+<br>
+    template <class U> friend class comma_iterator;<br>
+public:<br>
+    typedef          std::random_access_iterator_tag           iterator_category;<br>
+    typedef typename std::iterator_traits<It>::value_type      value_type;<br>
+    typedef typename std::iterator_traits<It>::difference_type difference_type;<br>
+    typedef It                                                 pointer;<br>
+    typedef typename std::iterator_traits<It>::reference       reference;<br>
+<br>
+    It base() const {return it_;}<br>
+<br>
+    comma_iterator() : it_() {}<br>
+    explicit comma_iterator(It it) : it_(it) {}<br>
+   template <class U><br>
+        comma_iterator(const comma_iterator<U>& u) :it_(u.it_) {}<br>
+<br>
+    reference operator*() const {return *it_;}<br>
+    pointer operator->() const {return it_;}<br>
+<br>
+    comma_iterator& operator++() {++it_; return *this;}<br>
+    comma_iterator operator++(int)<br>
+        {comma_iterator tmp(*this); ++(*this); return tmp;}<br>
+<br>
+    comma_iterator& operator--() {--it_; return *this;}<br>
+    comma_iterator operator--(int)<br>
+        {comma_iterator tmp(*this); --(*this); return tmp;}<br>
+<br>
+    comma_iterator& operator+=(difference_type n) {it_ += n; return *this;}<br>
+    comma_iterator operator+(difference_type n) const<br>
+        {comma_iterator tmp(*this); tmp += n; return tmp;}<br>
+    friend comma_iterator operator+(difference_type n, comma_iterator x)<br>
+        {x += n; return x;}<br>
+    comma_iterator& operator-=(difference_type n) {return *this += -n;}<br>
+    comma_iterator operator-(difference_type n) const<br>
+        {comma_iterator tmp(*this); tmp -= n; return tmp;}<br>
+<br>
+    reference operator[](difference_type n) const {return it_[n];}<br>
+    template <typename T><br>
+    void operator,(const T &) { assert(false); }<br>
+};<br>
+<br>
+template <class T, class U><br>
+inline<br>
+bool<br>
+operator==(const comma_iterator<T>& x, const comma_iterator<U>& y)<br>
+{<br>
+    return x.base() == y.base();<br>
+}<br>
+<br>
+template <class T, class U><br>
+inline<br>
+bool<br>
+operator!=(const comma_iterator<T>& x, const comma_iterator<U>& y)<br>
+{<br>
+    return !(x == y);<br>
+}<br>
+<br>
+template <class T, class U><br>
+inline<br>
+bool<br>
+operator<(const comma_iterator<T>& x, const comma_iterator<U>& y)<br>
+{<br>
+    return x.base() < y.base();<br>
+}<br>
+<br>
+template <class T, class U><br>
+inline<br>
+bool<br>
+operator<=(const comma_iterator<T>& x, const comma_iterator<U>& y)<br>
+{<br>
+    return !(y < x);<br>
+}<br>
+<br>
+template <class T, class U><br>
+inline<br>
+bool<br>
+operator>(const comma_iterator<T>& x, const comma_iterator<U>& y)<br>
+{<br>
+    return y < x;<br>
+}<br>
+<br>
+template <class T, class U><br>
+inline<br>
+bool<br>
+operator>=(const comma_iterator<T>& x, const comma_iterator<U>& y)<br>
+{<br>
+    return !(x < y);<br>
+}<br>
+<br>
+template <class T, class U><br>
+inline<br>
+typename std::iterator_traits<T>::difference_type<br>
+operator-(const comma_iterator<T>& x, const comma_iterator<U>& y)<br>
+{<br>
+    return x.base() - y.base();<br>
+}<br>
+<br>
+<br>
 template <class Iter><br>
 inline Iter base(output_iterator<Iter> i) { return i.base(); }<br>
<br>
@@ -299,6 +401,9 @@ inline Iter base(bidirectional_iterator<<br>
 template <class Iter><br>
 inline Iter base(random_access_iterator<Iter> i) { return i.base(); }<br>
<br>
+template <class Iter><br>
+inline Iter base(comma_iterator<Iter> i) { return i.base(); }<br>
+<br>
 template <class Iter>    // everything else<br>
 inline Iter base(Iter i) { return i; }<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>