diff --git a/stl/inc/ranges b/stl/inc/ranges index ef960d5722f..30531180aa6 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -2624,6 +2624,10 @@ namespace ranges { const auto _Size = static_cast>(size()); return counted_iterator(_RANGES begin(_Range), _Size); } + } else if constexpr (sized_sentinel_for, iterator_t<_Vw>>) { + auto _Iter = _RANGES begin(_Range); + const auto _Size = (_STD min)(_Count, _RANGES end(_Range) - _Iter); + return counted_iterator(_STD move(_Iter), _Size); } else { return counted_iterator(_RANGES begin(_Range), _Count); } @@ -2639,6 +2643,10 @@ namespace ranges { const auto _Size = static_cast>(size()); return counted_iterator(_RANGES begin(_Range), _Size); } + } else if constexpr (sized_sentinel_for, iterator_t>) { + auto _Iter = _RANGES begin(_Range); + const auto _Size = (_STD min)(_Count, _RANGES end(_Range) - _Iter); + return counted_iterator(_STD move(_Iter), _Size); } else { return counted_iterator(_RANGES begin(_Range), _Count); } @@ -2653,6 +2661,8 @@ namespace ranges { } else { return default_sentinel; } + } else if constexpr (sized_sentinel_for, iterator_t<_Vw>>) { + return default_sentinel; } else { return _Sentinel{_RANGES end(_Range)}; } @@ -2667,6 +2677,8 @@ namespace ranges { } else { return default_sentinel; } + } else if constexpr (sized_sentinel_for, iterator_t>) { + return default_sentinel; } else { return _Sentinel{_RANGES end(_Range)}; } diff --git a/tests/std/tests/P0896R4_views_take/test.cpp b/tests/std/tests/P0896R4_views_take/test.cpp index abb90762afd..3a868a43384 100644 --- a/tests/std/tests/P0896R4_views_take/test.cpp +++ b/tests/std/tests/P0896R4_views_take/test.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -507,6 +509,39 @@ void test_DevCom_1397309() { assert(ranges::equal(values | ranges::views::take(2) | ranges::views::keys, expected)); } +struct read_some_int_range : ranges::subrange>, default_sentinel_t> { + using ranges::subrange>, default_sentinel_t>::subrange; +}; + +template <> +inline constexpr bool ranges::disable_sized_range = true; + +void test_lwg3737() { + static_assert(ranges::input_range); + static_assert(ranges::input_range); + static_assert(!ranges::sized_range); + static_assert(!ranges::sized_range); + + istringstream stream{"0 1 42 1729"}; + auto rng = + read_some_int_range{counted_iterator{istream_iterator{stream}, 4}, default_sentinel} | views::take(2); + + using result_range = decltype(rng); + static_assert( + is_same_v, counted_iterator>>>); + static_assert(is_same_v, default_sentinel_t>); + + static_assert( + is_same_v, counted_iterator>>>); + static_assert(is_same_v, default_sentinel_t>); + + vector vec{}; + ranges::copy(rng, back_inserter(vec)); + + assert(ranges::size(vec) == 2); + assert((vec == vector{0, 1})); +} + int main() { // Validate views { // ... copyable @@ -576,4 +611,6 @@ int main() { } test_DevCom_1397309(); + + test_lwg3737(); }