From b405d54fcd60126cd14ffe71142a9066d34b009d Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 23 Aug 2016 11:13:26 +0100 Subject: [PATCH] Implement resolution of LWG DR 685 precisely PR libstdc++/71771 * include/bits/stl_iterator.h (operator-(reverse_iterator, reverse_iterator): Only define for C++98 mode. (operator-(move_iterator, move_iterator): 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 --- libstdc++-v3/ChangeLog | 16 ++ libstdc++-v3/include/bits/stl_iterator.h | 49 +++--- .../24_iterators/headers/iterator/synopsis.cc | 1 + .../headers/iterator/synopsis_c++11.cc | 165 +++++++++++++++++++ .../headers/iterator/synopsis_c++14.cc | 28 ++++ .../headers/iterator/synopsis_c++17.cc | 181 +++++++++++++++++++++ .../24_iterators/move_iterator/greedy_ops.cc | 2 +- .../24_iterators/reverse_iterator/71771.cc | 45 +++++ .../24_iterators/reverse_iterator/greedy_ops.cc | 4 +- 9 files changed, 462 insertions(+), 29 deletions(-) create mode 100644 libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++11.cc create mode 100644 libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++14.cc create mode 100644 libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++17.cc create mode 100644 libstdc++-v3/testsuite/24_iterators/reverse_iterator/71771.cc 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 + PR libstdc++/71771 + * include/bits/stl_iterator.h + (operator-(reverse_iterator, reverse_iterator): Only + define for C++98 mode. + (operator-(move_iterator, move_iterator): 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 - 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 - 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 @@ -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 + inline typename reverse_iterator<_Iterator>::difference_type + operator-(const reverse_iterator<_Iterator>& __x, + const reverse_iterator<_Iterator>& __y) + { return __y.base() - __x.base(); } template -#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 + 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 + 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 - 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 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 +// . + +#include + +namespace std { + + // C++11 24.4.4, iterator operations: + template + void + advance(InputIterator& i, Distance n); + + template + typename iterator_traits::difference_type + distance(InputIterator first, InputIterator last); + + template + ForwardIterator + next(ForwardIterator x, + typename iterator_traits::difference_type); + + template + BidirectionalIterator + prev(BidirectionalIterator x, + typename iterator_traits::difference_type); + + // C++11 24.5, Iterator adaptors: + template class reverse_iterator; + + template + bool operator==(const reverse_iterator& x, + const reverse_iterator& y); + + template + bool operator<(const reverse_iterator& x, + const reverse_iterator& y); + + template + bool operator!=(const reverse_iterator& x, + const reverse_iterator& y); + + template + bool operator>(const reverse_iterator& x, + const reverse_iterator& y); + + template + bool operator>=(const reverse_iterator& x, + const reverse_iterator& y); + + template + bool operator<=(const reverse_iterator& x, + const reverse_iterator& y); + + template + auto + operator-(const reverse_iterator& x, + const reverse_iterator& y) + -> decltype(x.base() - y.base()); + + template + reverse_iterator + operator+(typename reverse_iterator::difference_type n, + const reverse_iterator& x); + + template class back_insert_iterator; + + template + back_insert_iterator back_inserter(Container& x); + + template class front_insert_iterator; + + template + front_insert_iterator front_inserter(Container& x); + + template class insert_iterator; + + template + insert_iterator inserter(Container& x, Iterator i); + + template class move_iterator; + + template + bool operator==(const move_iterator& x, + const move_iterator& y); + + template + bool operator!=(const move_iterator& x, + const move_iterator& y); + + template + bool operator<(const move_iterator& x, + const move_iterator& y); + + template + bool operator<=(const move_iterator& x, + const move_iterator& y); + + template + bool operator>(const move_iterator& x, + const move_iterator& y); + + template + bool operator>=(const move_iterator& x, + const move_iterator& y); + + template + auto operator-(const move_iterator& x, + const move_iterator& y) + -> decltype(x.base() - y.base()); + + template + move_iterator + operator+(typename move_iterator::difference_type, + const move_iterator&); + + template + move_iterator make_move_iterator(const Iterator&); + + // 24.6, stream iterators: + template + class istream_iterator; + + template + bool operator==(const istream_iterator& x, + const istream_iterator& y); + + template + bool operator!=(const istream_iterator& x, + const istream_iterator& y); + + template + class ostream_iterator; + + template + class istreambuf_iterator; + + template + bool + operator==(const istreambuf_iterator&, + const istreambuf_iterator&); + + template + bool operator!=(const istreambuf_iterator&, + const istreambuf_iterator&); + + template + 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 +// . + +#include "./synopsis_c++11.cc" + +namespace std { + + // C++14 24.5, iterator adaptors: + template + reverse_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 +// . + +#include + +namespace std { + + // C++17 24.4.3, iterator operations: + template + constexpr void + advance(InputIterator& i, Distance n); + + template + constexpr typename iterator_traits::difference_type + distance(InputIterator first, InputIterator last); + + template + constexpr ForwardIterator + next(ForwardIterator x, + typename iterator_traits::difference_type); + + template + constexpr BidirectionalIterator + prev(BidirectionalIterator x, + typename iterator_traits::difference_type); + + // C++17 24.5, iterator adaptors: + template class reverse_iterator; + + template + constexpr + bool operator==(const reverse_iterator& x, + const reverse_iterator& y); + + template + constexpr + bool operator<(const reverse_iterator& x, + const reverse_iterator& y); + + template + constexpr + bool operator!=(const reverse_iterator& x, + const reverse_iterator& y); + + template + constexpr + bool operator>(const reverse_iterator& x, + const reverse_iterator& y); + + template + constexpr + bool operator>=(const reverse_iterator& x, + const reverse_iterator& y); + + template + constexpr + bool operator<=(const reverse_iterator& x, + const reverse_iterator& y); + + template + constexpr auto + operator-(const reverse_iterator& x, + const reverse_iterator& y) + -> decltype(x.base() - y.base()); + + template + constexpr reverse_iterator + operator+(typename reverse_iterator::difference_type n, + const reverse_iterator& x); + + template + constexpr reverse_iterator make_reverse_iterator(const Iterator&); + + template class back_insert_iterator; + + template + back_insert_iterator back_inserter(Container& x); + + template class front_insert_iterator; + + template + front_insert_iterator front_inserter(Container& x); + + template class insert_iterator; + + template + insert_iterator inserter(Container& x, Iterator i); + + template class move_iterator; + + template + constexpr + bool operator==(const move_iterator& x, + const move_iterator& y); + + template + constexpr + bool operator!=(const move_iterator& x, + const move_iterator& y); + + template + constexpr + bool operator<(const move_iterator& x, + const move_iterator& y); + + template + constexpr + bool operator<=(const move_iterator& x, + const move_iterator& y); + + template + constexpr + bool operator>(const move_iterator& x, + const move_iterator& y); + + template + constexpr + bool operator>=(const move_iterator& x, + const move_iterator& y); + + template + constexpr + auto operator-(const move_iterator& x, + const move_iterator& y) + -> decltype(x.base() - y.base()); + + template + constexpr move_iterator + operator+(typename move_iterator::difference_type, + const move_iterator&); + + template + constexpr move_iterator make_move_iterator(const Iterator&); + + // 24.6, stream iterators: + template + class istream_iterator; + + template + bool operator==(const istream_iterator& x, + const istream_iterator& y); + + template + bool operator!=(const istream_iterator& x, + const istream_iterator& y); + + template + class ostream_iterator; + + template + class istreambuf_iterator; + + template + bool + operator==(const istreambuf_iterator&, + const istreambuf_iterator&); + + template + bool operator!=(const istreambuf_iterator&, + const istreambuf_iterator&); + + template + 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 +// . + +// { dg-do compile { target c++11 } } + +#include +#include + +// PR libstdc++/71771 + +template +auto +diff2(std::reverse_iterator it1, std::reverse_iterator it2) +-> decltype(it1 - it2) +{ return it1 - it2; } + +template +void +diff2(Iter, Iter) +{ } + +void +test01() +{ + int i[2]; + __gnu_test::test_container + c(i); + using reverse_iterator + = std::reverse_iterator<__gnu_test::bidirectional_iterator_wrapper>; + 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; } -- 2.7.4