aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-08-23 11:13:26 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-08-23 11:13:26 +0100
commitb405d54fcd60126cd14ffe71142a9066d34b009d (patch)
tree8f1e862f81e10c13ee501a67012876febfc18151
parent06db992005654ed7993b9f7696e2c34751f82db2 (diff)
downloadgcc-b405d54fcd60126cd14ffe71142a9066d34b009d.zip
gcc-b405d54fcd60126cd14ffe71142a9066d34b009d.tar.gz
gcc-b405d54fcd60126cd14ffe71142a9066d34b009d.tar.bz2
Implement resolution of LWG DR 685 precisely
PR libstdc++/71771 * include/bits/stl_iterator.h (operator-(reverse_iterator<Iter>, reverse_iterator<Iter>): Only define for C++98 mode. (operator-(move_iterator<Iter>, move_iterator<Iter>): Don't define. * testsuite/24_iterators/headers/iterator/synopsis.cc: Use -std=gnu++98. * testsuite/24_iterators/headers/iterator/synopsis_c++11.cc: New test. * testsuite/24_iterators/headers/iterator/synopsis_c++14.cc: New test. * testsuite/24_iterators/headers/iterator/synopsis_c++17.cc: New test. * testsuite/24_iterators/move_iterator/greedy_ops.cc: Don't test difference operator. * testsuite/24_iterators/reverse_iterator/greedy_ops.cc: Only test difference operator for C++98. * testsuite/24_iterators/reverse_iterator/71771.cc: New test. From-SVN: r239691
-rw-r--r--libstdc++-v3/ChangeLog16
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h49
-rw-r--r--libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis.cc1
-rw-r--r--libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++11.cc165
-rw-r--r--libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++14.cc28
-rw-r--r--libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++17.cc181
-rw-r--r--libstdc++-v3/testsuite/24_iterators/move_iterator/greedy_ops.cc2
-rw-r--r--libstdc++-v3/testsuite/24_iterators/reverse_iterator/71771.cc45
-rw-r--r--libstdc++-v3/testsuite/24_iterators/reverse_iterator/greedy_ops.cc4
9 files changed, 462 insertions, 29 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ab0c91b..dc42ee4 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,21 @@
2016-08-23 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/71771
+ * include/bits/stl_iterator.h
+ (operator-(reverse_iterator<Iter>, reverse_iterator<Iter>): Only
+ define for C++98 mode.
+ (operator-(move_iterator<Iter>, move_iterator<Iter>): Don't define.
+ * testsuite/24_iterators/headers/iterator/synopsis.cc: Use
+ -std=gnu++98.
+ * testsuite/24_iterators/headers/iterator/synopsis_c++11.cc: New test.
+ * testsuite/24_iterators/headers/iterator/synopsis_c++14.cc: New test.
+ * testsuite/24_iterators/headers/iterator/synopsis_c++17.cc: New test.
+ * testsuite/24_iterators/move_iterator/greedy_ops.cc: Don't test
+ difference operator.
+ * testsuite/24_iterators/reverse_iterator/greedy_ops.cc: Only test
+ difference operator for C++98.
+ * testsuite/24_iterators/reverse_iterator/71771.cc: New test.
+
* include/bits/c++config (_GLIBCXX17_CONSTEXPR): Define.
* include/bits/range_access.h (begin, end, rbegin, rend, crbegin)
(crend): Add _GLIBCXX17_CONSTEXPR as per P0031R0.
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index 037e966..a98fff1 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -330,19 +330,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const reverse_iterator<_Iterator>& __y)
{ return !(__x < __y); }
- template<typename _Iterator>
- inline _GLIBCXX17_CONSTEXPR
- typename reverse_iterator<_Iterator>::difference_type
- operator-(const reverse_iterator<_Iterator>& __x,
- const reverse_iterator<_Iterator>& __y)
- { return __y.base() - __x.base(); }
-
- template<typename _Iterator>
- inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
- operator+(typename reverse_iterator<_Iterator>::difference_type __n,
- const reverse_iterator<_Iterator>& __x)
- { return reverse_iterator<_Iterator>(__x.base() - __n); }
-
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 280. Comparison of reverse_iterator to const reverse_iterator.
template<typename _IteratorL, typename _IteratorR>
@@ -380,21 +367,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator>=(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
{ return !(__x < __y); }
+ //@}
+
+#if __cplusplus < 201103L
+ template<typename _Iterator>
+ inline typename reverse_iterator<_Iterator>::difference_type
+ operator-(const reverse_iterator<_Iterator>& __x,
+ const reverse_iterator<_Iterator>& __y)
+ { return __y.base() - __x.base(); }
template<typename _IteratorL, typename _IteratorR>
-#if __cplusplus >= 201103L
- // DR 685.
- inline _GLIBCXX17_CONSTEXPR auto
+ inline typename reverse_iterator<_IteratorL>::difference_type
operator-(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
- -> decltype(__y.base() - __x.base())
+ { return __y.base() - __x.base(); }
#else
- inline typename reverse_iterator<_IteratorL>::difference_type
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // DR 685. reverse_iterator/move_iterator difference has invalid signatures
+ template<typename _IteratorL, typename _IteratorR>
+ inline _GLIBCXX17_CONSTEXPR auto
operator-(const reverse_iterator<_IteratorL>& __x,
const reverse_iterator<_IteratorR>& __y)
-#endif
+ -> decltype(__y.base() - __x.base())
{ return __y.base() - __x.base(); }
- //@}
+#endif
+
+ template<typename _Iterator>
+ inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
+ operator+(typename reverse_iterator<_Iterator>::difference_type __n,
+ const reverse_iterator<_Iterator>& __x)
+ { return reverse_iterator<_Iterator>(__x.base() - __n); }
#if __cplusplus >= 201103L
// Same as C++14 make_reverse_iterator but used in C++03 mode too.
@@ -1192,13 +1194,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __x.base() - __y.base(); }
template<typename _Iterator>
- inline _GLIBCXX17_CONSTEXPR auto
- operator-(const move_iterator<_Iterator>& __x,
- const move_iterator<_Iterator>& __y)
- -> decltype(__x.base() - __y.base())
- { return __x.base() - __y.base(); }
-
- template<typename _Iterator>
inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
operator+(typename move_iterator<_Iterator>::difference_type __n,
const move_iterator<_Iterator>& __x)
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis.cc
index ed01258..35284d0 100644
--- a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis.cc
+++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis.cc
@@ -1,3 +1,4 @@
+// { dg-options "-std=gnu++98" }
// { dg-do compile }
// Copyright (C) 2007-2016 Free Software Foundation, Inc.
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++11.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++11.cc
new file mode 100644
index 0000000..f0b620f
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++11.cc
@@ -0,0 +1,165 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <iterator>
+
+namespace std {
+
+ // C++11 24.4.4, iterator operations:
+ template <class InputIterator, class Distance>
+ void
+ advance(InputIterator& i, Distance n);
+
+ template <class InputIterator>
+ typename iterator_traits<InputIterator>::difference_type
+ distance(InputIterator first, InputIterator last);
+
+ template<class ForwardIterator>
+ ForwardIterator
+ next(ForwardIterator x,
+ typename iterator_traits<ForwardIterator>::difference_type);
+
+ template<class BidirectionalIterator>
+ BidirectionalIterator
+ prev(BidirectionalIterator x,
+ typename iterator_traits<BidirectionalIterator>::difference_type);
+
+ // C++11 24.5, Iterator adaptors:
+ template <class Iterator> class reverse_iterator;
+
+ template <class Iterator1, class Iterator2>
+ bool operator==(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator<(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator!=(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator>(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator>=(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator<=(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ auto
+ operator-(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y)
+ -> decltype(x.base() - y.base());
+
+ template <class Iterator>
+ reverse_iterator<Iterator>
+ operator+(typename reverse_iterator<Iterator>::difference_type n,
+ const reverse_iterator<Iterator>& x);
+
+ template <class Container> class back_insert_iterator;
+
+ template <class Container>
+ back_insert_iterator<Container> back_inserter(Container& x);
+
+ template <class Container> class front_insert_iterator;
+
+ template <class Container>
+ front_insert_iterator<Container> front_inserter(Container& x);
+
+ template <class Container> class insert_iterator;
+
+ template <class Container, class Iterator>
+ insert_iterator<Container> inserter(Container& x, Iterator i);
+
+ template <class Iterator> class move_iterator;
+
+ template <class Iterator1, class Iterator2>
+ bool operator==(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator!=(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator<(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator<=(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator>(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ bool operator>=(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ auto operator-(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y)
+ -> decltype(x.base() - y.base());
+
+ template <class Iterator>
+ move_iterator<Iterator>
+ operator+(typename move_iterator<Iterator>::difference_type,
+ const move_iterator<Iterator>&);
+
+ template <class Iterator>
+ move_iterator<Iterator> make_move_iterator(const Iterator&);
+
+ // 24.6, stream iterators:
+ template <class T, class charT, class traits, class Distance>
+ class istream_iterator;
+
+ template <class T, class charT, class traits, class Distance>
+ bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
+ const istream_iterator<T,charT,traits,Distance>& y);
+
+ template <class T, class charT, class traits, class Distance>
+ bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
+ const istream_iterator<T,charT,traits,Distance>& y);
+
+ template <class T, class charT, class traits>
+ class ostream_iterator;
+
+ template<class charT, class traits>
+ class istreambuf_iterator;
+
+ template <class charT, class traits>
+ bool
+ operator==(const istreambuf_iterator<charT,traits>&,
+ const istreambuf_iterator<charT,traits>&);
+
+ template <class charT, class traits>
+ bool operator!=(const istreambuf_iterator<charT,traits>&,
+ const istreambuf_iterator<charT,traits>&);
+
+ template <class charT, class traits>
+ class ostreambuf_iterator;
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++14.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++14.cc
new file mode 100644
index 0000000..7f6063f
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++14.cc
@@ -0,0 +1,28 @@
+// { dg-options "-std=gnu++14" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "./synopsis_c++11.cc"
+
+namespace std {
+
+ // C++14 24.5, iterator adaptors:
+ template <class Iterator>
+ reverse_iterator<Iterator> make_reverse_iterator(const Iterator&);
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++17.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++17.cc
new file mode 100644
index 0000000..c2adc40
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++17.cc
@@ -0,0 +1,181 @@
+// { dg-options "-std=gnu++17" }
+// { dg-do compile }
+
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <iterator>
+
+namespace std {
+
+ // C++17 24.4.3, iterator operations:
+ template <class InputIterator, class Distance>
+ constexpr void
+ advance(InputIterator& i, Distance n);
+
+ template <class InputIterator>
+ constexpr typename iterator_traits<InputIterator>::difference_type
+ distance(InputIterator first, InputIterator last);
+
+ template <class ForwardIterator>
+ constexpr ForwardIterator
+ next(ForwardIterator x,
+ typename iterator_traits<ForwardIterator>::difference_type);
+
+ template <class BidirectionalIterator>
+ constexpr BidirectionalIterator
+ prev(BidirectionalIterator x,
+ typename iterator_traits<BidirectionalIterator>::difference_type);
+
+ // C++17 24.5, iterator adaptors:
+ template <class Iterator> class reverse_iterator;
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator==(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator<(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator!=(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator>(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator>=(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator<=(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr auto
+ operator-(const reverse_iterator<Iterator1>& x,
+ const reverse_iterator<Iterator2>& y)
+ -> decltype(x.base() - y.base());
+
+ template <class Iterator>
+ constexpr reverse_iterator<Iterator>
+ operator+(typename reverse_iterator<Iterator>::difference_type n,
+ const reverse_iterator<Iterator>& x);
+
+ template <class Iterator>
+ constexpr reverse_iterator<Iterator> make_reverse_iterator(const Iterator&);
+
+ template <class Container> class back_insert_iterator;
+
+ template <class Container>
+ back_insert_iterator<Container> back_inserter(Container& x);
+
+ template <class Container> class front_insert_iterator;
+
+ template <class Container>
+ front_insert_iterator<Container> front_inserter(Container& x);
+
+ template <class Container> class insert_iterator;
+
+ template <class Container, class Iterator>
+ insert_iterator<Container> inserter(Container& x, Iterator i);
+
+ template <class Iterator> class move_iterator;
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator==(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator!=(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator<(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator<=(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator>(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ bool operator>=(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y);
+
+ template <class Iterator1, class Iterator2>
+ constexpr
+ auto operator-(const move_iterator<Iterator1>& x,
+ const move_iterator<Iterator2>& y)
+ -> decltype(x.base() - y.base());
+
+ template <class Iterator>
+ constexpr move_iterator<Iterator>
+ operator+(typename move_iterator<Iterator>::difference_type,
+ const move_iterator<Iterator>&);
+
+ template <class Iterator>
+ constexpr move_iterator<Iterator> make_move_iterator(const Iterator&);
+
+ // 24.6, stream iterators:
+ template <class T, class charT, class traits, class Distance>
+ class istream_iterator;
+
+ template <class T, class charT, class traits, class Distance>
+ bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
+ const istream_iterator<T,charT,traits,Distance>& y);
+
+ template <class T, class charT, class traits, class Distance>
+ bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
+ const istream_iterator<T,charT,traits,Distance>& y);
+
+ template <class T, class charT, class traits>
+ class ostream_iterator;
+
+ template<class charT, class traits>
+ class istreambuf_iterator;
+
+ template <class charT, class traits>
+ bool
+ operator==(const istreambuf_iterator<charT,traits>&,
+ const istreambuf_iterator<charT,traits>&);
+
+ template <class charT, class traits>
+ bool operator!=(const istreambuf_iterator<charT,traits>&,
+ const istreambuf_iterator<charT,traits>&);
+
+ template <class charT, class traits>
+ class ostreambuf_iterator;
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/move_iterator/greedy_ops.cc b/libstdc++-v3/testsuite/24_iterators/move_iterator/greedy_ops.cc
index 655313a..e546e19 100644
--- a/libstdc++-v3/testsuite/24_iterators/move_iterator/greedy_ops.cc
+++ b/libstdc++-v3/testsuite/24_iterators/move_iterator/greedy_ops.cc
@@ -32,7 +32,7 @@ void test01()
it <= it;
it > it;
it >= it;
- it - it;
+ // it - it; // See PR libstdc++/71771
1 + it;
it + 1;
}
diff --git a/libstdc++-v3/testsuite/24_iterators/reverse_iterator/71771.cc b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/71771.cc
new file mode 100644
index 0000000..41b5086
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/71771.cc
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <iterator>
+#include <testsuite_iterators.h>
+
+// PR libstdc++/71771
+
+template<typename Iter>
+auto
+diff2(std::reverse_iterator<Iter> it1, std::reverse_iterator<Iter> it2)
+-> decltype(it1 - it2)
+{ return it1 - it2; }
+
+template<typename Iter>
+void
+diff2(Iter, Iter)
+{ }
+
+void
+test01()
+{
+ int i[2];
+ __gnu_test::test_container<int, __gnu_test::bidirectional_iterator_wrapper>
+ c(i);
+ using reverse_iterator
+ = std::reverse_iterator<__gnu_test::bidirectional_iterator_wrapper<int>>;
+ diff2(reverse_iterator(c.end()), reverse_iterator(c.begin()));
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/reverse_iterator/greedy_ops.cc b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/greedy_ops.cc
index 05aa340..1360029 100644
--- a/libstdc++-v3/testsuite/24_iterators/reverse_iterator/greedy_ops.cc
+++ b/libstdc++-v3/testsuite/24_iterators/reverse_iterator/greedy_ops.cc
@@ -31,7 +31,9 @@ void test01()
it <= it;
it > it;
it >= it;
- it - it;
+#if __cplusplus < 201103L
+ it - it; // See PR libstdc++/71771
+#endif
1 + it;
it + 1;
}