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.
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>
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.
-> decltype(__x.base() - __y.base())
{ 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,
+// { dg-options "-std=gnu++98" }
// { dg-do compile }
// Copyright (C) 2007-2016 Free Software Foundation, Inc.
--- /dev/null
+// { 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;
+}
--- /dev/null
+// { 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&);
+}
--- /dev/null
+// { 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;
+}
it <= it;
it > it;
it >= it;
- it - it;
+ // it - it; // See PR libstdc++/71771
1 + it;
it + 1;
}
--- /dev/null
+// 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()));
+}
it <= it;
it > it;
it >= it;
- it - it;
+#if __cplusplus < 201103L
+ it - it; // See PR libstdc++/71771
+#endif
1 + it;
it + 1;
}