On Thu, 10 Feb 2022, Patrick Palka wrote: > Tested on x86_64-pc-linux-gnu, does this look OK for the 11 branch? > The backport to the 10 branch hasn't been started yet, I figured it'd > be good to first get the 11 backport right then base the 10 backport > on the 11 one. > > NB: This backport of r12-1606 to the 11 branch deliberately omits parts > of P2325R3 so as to maximize backward compatibility with pre-P2325R3 code. > In particular, we don't remove the default ctors for back_insert_iterator, > front_insert_iterator, ostream_iterator, ref_view and basic_istream_view.
FWIW here's a diff of the changes in this backport relative to r12-1606: libstdc++-v3/include/bits/stl_iterator.h | 13 ++++++++++- libstdc++-v3/include/bits/stream_iterator.h | 5 +++++ libstdc++-v3/include/std/ranges | 24 +++++++++++++++------ .../24_iterators/back_insert_iterator/constexpr.cc | 3 ++- .../front_insert_iterator/constexpr.cc | 3 ++- .../ostream_iterator/requirements/constexpr.cc | 24 +++++++++++++++++++++ libstdc++-v3/testsuite/std/ranges/97600.cc | 3 ++- libstdc++-v3/testsuite/std/ranges/p2325.cc | 25 ++++++++++++++++++++++ 8 files changed, 89 insertions(+), 11 deletions(-) diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 7fe727d8093..549bc26dee5 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -639,6 +639,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Container container_type; #if __cplusplus > 201703L using difference_type = ptrdiff_t; + + constexpr back_insert_iterator() noexcept : container(nullptr) { } #endif /// The only way to create this %iterator is with a container. @@ -740,6 +742,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Container container_type; #if __cplusplus > 201703L using difference_type = ptrdiff_t; + + constexpr front_insert_iterator() noexcept : container(nullptr) { } #endif /// The only way to create this %iterator is with a container. @@ -839,12 +843,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { #if __cplusplus > 201703L && defined __cpp_lib_concepts using _Iter = std::__detail::__range_iter_t<_Container>; + + protected: + _Container* container = nullptr; + _Iter iter = _Iter(); #else typedef typename _Container::iterator _Iter; -#endif + protected: _Container* container; _Iter iter; +#endif public: /// A nested typedef for the type of whatever container you used. @@ -852,6 +861,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus > 201703L && defined __cpp_lib_concepts using difference_type = ptrdiff_t; + + insert_iterator() = default; #endif /** diff --git a/libstdc++-v3/include/bits/stream_iterator.h b/libstdc++-v3/include/bits/stream_iterator.h index d07474d4996..fd8920b8d01 100644 --- a/libstdc++-v3/include/bits/stream_iterator.h +++ b/libstdc++-v3/include/bits/stream_iterator.h @@ -192,6 +192,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const _CharT* _M_string; public: +#if __cplusplus > 201703L + constexpr ostream_iterator() noexcept + : _M_stream(nullptr), _M_string(nullptr) { } +#endif + /// Construct from an ostream. ostream_iterator(ostream_type& __s) : _M_stream(std::__addressof(__s)), _M_string(0) {} diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index a01b5e79f1f..bf6cfae2a6e 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -680,6 +680,8 @@ namespace views : public view_interface<basic_istream_view<_Val, _CharT, _Traits>> { public: + basic_istream_view() = default; + constexpr explicit basic_istream_view(basic_istream<_CharT, _Traits>& __stream) : _M_stream(std::__addressof(__stream)) @@ -688,7 +690,8 @@ namespace views constexpr auto begin() { - *_M_stream >> _M_object; + if (_M_stream != nullptr) + *_M_stream >> _M_object; return _Iterator{this}; } @@ -697,8 +700,8 @@ namespace views { return default_sentinel; } private: - basic_istream<_CharT, _Traits>* _M_stream; - _Val _M_object; + basic_istream<_CharT, _Traits>* _M_stream = nullptr; + _Val _M_object = _Val(); struct _Iterator { @@ -720,6 +723,7 @@ namespace views _Iterator& operator++() { + __glibcxx_assert(_M_parent->_M_stream != nullptr); *_M_parent->_M_stream >> _M_parent->_M_object; return *this; } @@ -730,18 +734,21 @@ namespace views _Val& operator*() const - { return _M_parent->_M_object; } + { + __glibcxx_assert(_M_parent->_M_stream != nullptr); + return _M_parent->_M_object; + } friend bool operator==(const _Iterator& __x, default_sentinel_t) { return __x._M_at_end(); } private: - basic_istream_view* _M_parent; + basic_istream_view* _M_parent = nullptr; bool _M_at_end() const - { return !*_M_parent->_M_stream; } + { return _M_parent == nullptr || !*_M_parent->_M_stream; } }; friend _Iterator; @@ -1045,12 +1052,15 @@ namespace views::__adaptor class ref_view : public view_interface<ref_view<_Range>> { private: - _Range* _M_r; + _Range* _M_r = nullptr; static void _S_fun(_Range&); // not defined static void _S_fun(_Range&&) = delete; public: + constexpr + ref_view() noexcept = default; + template<__detail::__not_same_as<ref_view> _Tp> requires convertible_to<_Tp, _Range&> && requires { _S_fun(declval<_Tp>()); } diff --git a/libstdc++-v3/testsuite/24_iterators/back_insert_iterator/constexpr.cc b/libstdc++-v3/testsuite/24_iterators/back_insert_iterator/constexpr.cc index 27acd071df1..bef2289ba79 100644 --- a/libstdc++-v3/testsuite/24_iterators/back_insert_iterator/constexpr.cc +++ b/libstdc++-v3/testsuite/24_iterators/back_insert_iterator/constexpr.cc @@ -42,7 +42,8 @@ constexpr bool test01() { container c; - std::back_insert_iterator<container> iter = std::back_inserter(c); + std::back_insert_iterator<container> iter; + iter = std::back_inserter(c); *iter++ = 1; int i = 2; *iter = i; diff --git a/libstdc++-v3/testsuite/24_iterators/front_insert_iterator/constexpr.cc b/libstdc++-v3/testsuite/24_iterators/front_insert_iterator/constexpr.cc index cff7f6a4524..7b4c990b107 100644 --- a/libstdc++-v3/testsuite/24_iterators/front_insert_iterator/constexpr.cc +++ b/libstdc++-v3/testsuite/24_iterators/front_insert_iterator/constexpr.cc @@ -42,7 +42,8 @@ constexpr bool test01() { container c; - std::front_insert_iterator<container> iter = std::front_inserter(c); + std::front_insert_iterator<container> iter; + iter = std::front_inserter(c); *iter++ = 1; int i = 2; *iter = i; diff --git a/libstdc++-v3/testsuite/24_iterators/ostream_iterator/requirements/constexpr.cc b/libstdc++-v3/testsuite/24_iterators/ostream_iterator/requirements/constexpr.cc new file mode 100644 index 00000000000..4edaaa8aebb --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/ostream_iterator/requirements/constexpr.cc @@ -0,0 +1,24 @@ +// Copyright (C) 2019-2021 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-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include <iterator> + +constexpr std::ostream_iterator<int> iter1; +constexpr std::ostream_iterator<int> iter2{}; diff --git a/libstdc++-v3/testsuite/std/ranges/97600.cc b/libstdc++-v3/testsuite/std/ranges/97600.cc index c642b9d22d0..7435de022cd 100644 --- a/libstdc++-v3/testsuite/std/ranges/97600.cc +++ b/libstdc++-v3/testsuite/std/ranges/97600.cc @@ -24,8 +24,9 @@ #include <ranges> void -test01(std::ranges::basic_istream_view<int, char, std::char_traits<char>> v) +test01() { + std::ranges::basic_istream_view<int, char, std::char_traits<char>> v; v.begin(); static_assert(std::ranges::range<decltype(v)>); } diff --git a/libstdc++-v3/testsuite/std/ranges/p2325.cc b/libstdc++-v3/testsuite/std/ranges/p2325.cc index df6cde29e4d..72ba5c4a35d 100644 --- a/libstdc++-v3/testsuite/std/ranges/p2325.cc +++ b/libstdc++-v3/testsuite/std/ranges/p2325.cc @@ -2,6 +2,12 @@ // { dg-do compile { target c++20 } } // P2325R3 "Views should not be required to be default constructible" +// Parts of P2325R3 are deliberately omitted in libstdc++ 11, in particular the +// removal of default ctors for back_/front_insert_iterator, ostream_iterator, +// ref_view and basic_istream_view/::iterator, so as to maximize backward +// compatibility with pre-P2325R3 code. So most static_asserts in this test fail, +// see the xfails at the end of this file. + #include <ranges> #include <iterator> #include <span> @@ -153,3 +159,22 @@ test11() using type2 = ranges::elements_view<ranges::single_view<pair<int,int>>, 0>; static_assert(default_initializable<type2>); } + +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 35 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 36 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 37 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 38 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 43 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 47 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 57 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 58 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 63 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 67 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 76 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 84 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 124 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 126 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 128 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 138 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 148 } +// { dg-bogus "static assertion failed" "" { xfail *-*-* } 158 }