diff options
author | Patrick Palka <ppalka@redhat.com> | 2024-10-22 17:01:59 -0400 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2024-10-22 17:01:59 -0400 |
commit | f191c8301545658543773ba3d0e6f3f0927529e0 (patch) | |
tree | add8e16c85cb94160f9969ba2e2a284395850983 | |
parent | a6db5908a55adbef0a0dc1eb2a22743064fe17b8 (diff) | |
download | gcc-f191c8301545658543773ba3d0e6f3f0927529e0.zip gcc-f191c8301545658543773ba3d0e6f3f0927529e0.tar.gz gcc-f191c8301545658543773ba3d0e6f3f0927529e0.tar.bz2 |
libstdc++: Implement LWG 4166 changes to concat_view::end()
This patch proactively implements the proposed resolution for this LWG
issue, which seems straightforward and slated to get approved as-is.
(No _GLIBCXX_RESOLVE_LIB_DEFECTS code comment is added since concat_view
is C++26, so this isn't a defect against a published standard.)
libstdc++-v3/ChangeLog:
* include/std/ranges (concat_view::begin): Add space after
'requires' starting a requires-clause.
(concat_view::end): Likewise. Refine condition for returning an
iterator rather than default_sentinel as per LWG 4166.
* testsuite/std/ranges/concat/1.cc (test03): Verify LWG 4166
example.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
-rw-r--r-- | libstdc++-v3/include/std/ranges | 10 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/ranges/concat/1.cc | 20 |
2 files changed, 26 insertions, 4 deletions
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 9f23372..cebe106 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -9687,7 +9687,7 @@ namespace ranges { } constexpr iterator<false> - begin() requires(!(__detail::__simple_view<_Vs> && ...)) + begin() requires (!(__detail::__simple_view<_Vs> && ...)) { iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views))); __it.template _M_satisfy<0>(); @@ -9703,9 +9703,10 @@ namespace ranges } constexpr auto - end() requires(!(__detail::__simple_view<_Vs> && ...)) + end() requires (!(__detail::__simple_view<_Vs> && ...)) { - if constexpr (__detail::__last_is_common<_Vs...>::value) + if constexpr ((semiregular<iterator_t<_Vs>> && ...) + && __detail::__last_is_common<_Vs...>::value) { constexpr auto __n = sizeof...(_Vs); return iterator<false>(this, in_place_index<__n - 1>, @@ -9718,7 +9719,8 @@ namespace ranges constexpr auto end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...> { - if constexpr (__detail::__last_is_common<const _Vs...>::value) + if constexpr ((semiregular<iterator_t<const _Vs>> && ...) + && __detail::__last_is_common<const _Vs...>::value) { constexpr auto __n = sizeof...(_Vs); return iterator<true>(this, in_place_index<__n - 1>, diff --git a/libstdc++-v3/testsuite/std/ranges/concat/1.cc b/libstdc++-v3/testsuite/std/ranges/concat/1.cc index 6ffe28e..e5d10f4 100644 --- a/libstdc++-v3/testsuite/std/ranges/concat/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/concat/1.cc @@ -10,6 +10,7 @@ #include <algorithm> #include <vector> #include <array> +#include <sstream> #include <utility> #include <testsuite_hooks.h> #include <testsuite_iterators.h> @@ -66,9 +67,28 @@ test02() VERIFY( ranges::equal(v | views::drop(1), x) ); } +void +test03() +{ + // LWG 4166 - concat_view::end() should be more constrained in order to + // support noncopyable iterators + auto range_copyable_it = std::vector<int>{1, 2, 3}; + + std::stringstream ss{"4 5 6"}; + auto range_noncopyable_it = views::istream<int>(ss); + ranges::range auto view1 = views::concat(range_copyable_it, range_noncopyable_it); + VERIFY( ranges::equal(view1, std::vector{1, 2, 3, 4, 5, 6}) ); + + ss = std::stringstream{"4 5 6"}; + range_noncopyable_it = views::istream<int>(ss); + ranges::range auto view2 = views::concat(range_noncopyable_it, range_copyable_it); + VERIFY( ranges::equal(view2, std::vector{4, 5, 6, 1, 2, 3}) ); +} + int main() { static_assert(test01()); test02(); + test03(); } |