diff --git a/stl/inc/ranges b/stl/inc/ranges index eb1b986d1ae..f5a1019814d 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -1988,6 +1988,9 @@ namespace ranges { template take_view(_Rng&&, range_difference_t<_Rng>) -> take_view>; + template + inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Rng>; + namespace views { // VARIABLE views::take template @@ -2394,6 +2397,9 @@ namespace ranges { template drop_view(_Rng&&, range_difference_t<_Rng>) -> drop_view>; + template + inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Rng>; + namespace views { // VARIABLE views::drop class _Drop_fn { @@ -2550,6 +2556,9 @@ namespace ranges { template drop_while_view(_Rng&&, _Pr) -> drop_while_view, _Pr>; + template + inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Rng>; + namespace views { // VARIABLE views::drop_while class _Drop_while_fn { @@ -3502,6 +3511,9 @@ namespace ranges { template common_view(_Rng&&) -> common_view>; + template + inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Rng>; + namespace views { // VARIABLE views::common class _Common_fn : public _Pipe::_Base<_Common_fn> { @@ -3614,6 +3626,9 @@ namespace ranges { template reverse_view(_Rng&&) -> reverse_view>; + template + inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Rng>; + namespace views { // VARIABLE views::reverse template @@ -4065,6 +4080,9 @@ namespace ranges { } }; + template + inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Rng>; + template using keys_view = elements_view, 0>; template diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 74ea3106ef3..7a18d3333ff 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -240,6 +240,7 @@ // P1976R2 Explicit Constructors For Fixed-Extent span From Dynamic-Extent Ranges // P1983R0 Fixing Minor Ranges Issues // P1994R1 elements_view Needs Its Own sentinel +// P2017R1 Conditionally Borrowed Ranges // P2091R0 Fixing Issues With Range Access CPOs // P2102R0 Making "Implicit Expression Variations" More Explicit // P2106R0 Range Algorithm Result Types diff --git a/tests/std/tests/P0896R4_views_common/test.cpp b/tests/std/tests/P0896R4_views_common/test.cpp index 65aa11ba02e..6028381dca4 100644 --- a/tests/std/tests/P0896R4_views_common/test.cpp +++ b/tests/std/tests/P0896R4_views_common/test.cpp @@ -74,7 +74,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { using ranges::common_view, ranges::bidirectional_range, ranges::common_range, ranges::contiguous_range, ranges::enable_borrowed_range, ranges::forward_range, ranges::input_range, ranges::iterator_t, ranges::prev, ranges::random_access_range, ranges::range, ranges::range_reference_t, ranges::size, ranges::sized_range, - ranges::range_size_t; + ranges::range_size_t, ranges::borrowed_range; constexpr bool is_view = ranges::view>; using V = views::all_t; @@ -316,8 +316,17 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { } // Validate view_interface::data - static_assert(!CanData); - static_assert(!CanData); + static_assert(CanMemberData == (contiguous_range && sized_range) ); + static_assert(contiguous_range == CanMemberData); + if constexpr (CanMemberData) { + assert(r.data() == &*r.begin()); + } + static_assert(CanMemberData == (contiguous_range && sized_range) ); + static_assert(contiguous_range == CanMemberData); + if constexpr (CanMemberData) { + assert(as_const(r).data() == &*as_const(r).begin()); + } + if (!is_constant_evaluated() && !is_empty) { // Validate view_interface::operator[] if constexpr (CanIndex) { @@ -362,6 +371,9 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { if (!is_empty) { assert(*b2.begin() == *begin(expected)); } + + // Validate borrowed_range + static_assert(borrowed_range == borrowed_range); } return true; diff --git a/tests/std/tests/P0896R4_views_drop/test.cpp b/tests/std/tests/P0896R4_views_drop/test.cpp index 2e154446815..a05668b8e7c 100644 --- a/tests/std/tests/P0896R4_views_drop/test.cpp +++ b/tests/std/tests/P0896R4_views_drop/test.cpp @@ -81,7 +81,7 @@ concept CanViewDrop = requires(Rng&& r) { template constexpr bool test_one(Rng&& rng, Expected&& expected) { using ranges::drop_view, ranges::common_range, ranges::enable_borrowed_range, ranges::iterator_t, ranges::prev, - ranges::range, ranges::sentinel_t, ranges::sized_range; + ranges::range, ranges::sentinel_t, ranges::sized_range, ranges::borrowed_range; using ranges::input_range, ranges::forward_range, ranges::bidirectional_range, ranges::random_access_range, ranges::contiguous_range; @@ -209,6 +209,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { STATIC_ASSERT(bidirectional_range == bidirectional_range); STATIC_ASSERT(random_access_range == random_access_range); STATIC_ASSERT(contiguous_range == contiguous_range); + STATIC_ASSERT(borrowed_range == borrowed_range); // Validate drop_view::size STATIC_ASSERT(CanMemberSize == CanSize); @@ -516,4 +517,17 @@ int main() { STATIC_ASSERT((instantiation_test(), true)); instantiation_test(); + + { + // Validate a non-view borrowed range + constexpr span s{some_ints}; + STATIC_ASSERT(test_one(s, only_four_ints)); + test_one(s, only_four_ints); + + // Validate a view borrowed range + constexpr auto v = + views::iota(0ull, ranges::size(some_ints)) | views::transform([](auto i) { return some_ints[i]; }); + STATIC_ASSERT(test_one(v, only_four_ints)); + test_one(v, only_four_ints); + } } diff --git a/tests/std/tests/P0896R4_views_drop_while/test.cpp b/tests/std/tests/P0896R4_views_drop_while/test.cpp index 874e30a4541..fe36b6b11cd 100644 --- a/tests/std/tests/P0896R4_views_drop_while/test.cpp +++ b/tests/std/tests/P0896R4_views_drop_while/test.cpp @@ -36,7 +36,7 @@ template constexpr bool test_one(Rng&& rng, Expected&& expected) { using ranges::drop_while_view, ranges::bidirectional_range, ranges::common_range, ranges::contiguous_range, ranges::enable_borrowed_range, ranges::forward_range, ranges::iterator_t, ranges::prev, - ranges::random_access_range; + ranges::random_access_range, ranges::borrowed_range; constexpr bool is_view = ranges::view>; @@ -48,6 +48,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { STATIC_ASSERT(bidirectional_range == bidirectional_range); STATIC_ASSERT(random_access_range == random_access_range); STATIC_ASSERT(contiguous_range == contiguous_range); + STATIC_ASSERT(borrowed_range == borrowed_range); // Validate range adaptor object and range adaptor closure constexpr auto closure = views::drop_while(is_less_than<3>); diff --git a/tests/std/tests/P0896R4_views_elements/test.cpp b/tests/std/tests/P0896R4_views_elements/test.cpp index 910ded5e096..f1ee7dcec74 100644 --- a/tests/std/tests/P0896R4_views_elements/test.cpp +++ b/tests/std/tests/P0896R4_views_elements/test.cpp @@ -36,7 +36,8 @@ template constexpr bool test_one(Rng&& rng) { using ranges::elements_view, ranges::bidirectional_range, ranges::common_range, ranges::contiguous_range, ranges::enable_borrowed_range, ranges::forward_range, ranges::input_range, ranges::iterator_t, ranges::prev, - ranges::random_access_range, ranges::range, ranges::range_reference_t, ranges::sentinel_t; + ranges::random_access_range, ranges::range, ranges::range_reference_t, ranges::sentinel_t, + ranges::borrowed_range; using V = views::all_t; using R = elements_view; @@ -46,6 +47,7 @@ constexpr bool test_one(Rng&& rng) { STATIC_ASSERT(bidirectional_range == bidirectional_range); STATIC_ASSERT(random_access_range == random_access_range); STATIC_ASSERT(!contiguous_range); + STATIC_ASSERT(borrowed_range == borrowed_range); // ... with lvalue argument STATIC_ASSERT(CanViewElements); diff --git a/tests/std/tests/P0896R4_views_reverse/test.cpp b/tests/std/tests/P0896R4_views_reverse/test.cpp index 3fdf5315a70..be463bfd8f7 100644 --- a/tests/std/tests/P0896R4_views_reverse/test.cpp +++ b/tests/std/tests/P0896R4_views_reverse/test.cpp @@ -26,7 +26,7 @@ template constexpr bool test_one(Rng&& rng, Expected&& expected) { using ranges::common_range, ranges::reverse_view, ranges::sized_range, ranges::begin, ranges::end, ranges::size, ranges::iterator_t, ranges::range_size_t, ranges::random_access_range, ranges::prev, - ranges::enable_borrowed_range; + ranges::enable_borrowed_range, ranges::borrowed_range; constexpr bool is_view = ranges::view>; using V = views::all_t; @@ -35,6 +35,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { static_assert(ranges::bidirectional_range); static_assert(random_access_range == random_access_range); static_assert(!ranges::contiguous_range); + static_assert(borrowed_range == borrowed_range); // Validate range adapter object // ...with lvalue argument diff --git a/tests/std/tests/P0896R4_views_take/test.cpp b/tests/std/tests/P0896R4_views_take/test.cpp index 43633d922d1..9d26ae93dfe 100644 --- a/tests/std/tests/P0896R4_views_take/test.cpp +++ b/tests/std/tests/P0896R4_views_take/test.cpp @@ -84,7 +84,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { using ranges::input_range, ranges::forward_range, ranges::bidirectional_range, ranges::random_access_range, ranges::contiguous_range; using ranges::take_view, ranges::common_range, ranges::enable_borrowed_range, ranges::iterator_t, ranges::prev, - ranges::range, ranges::sentinel_t, ranges::sized_range; + ranges::range, ranges::sentinel_t, ranges::sized_range, ranges::borrowed_range; constexpr bool is_view = ranges::view>; @@ -209,6 +209,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { STATIC_ASSERT(bidirectional_range == bidirectional_range); STATIC_ASSERT(random_access_range == random_access_range); STATIC_ASSERT(contiguous_range == contiguous_range); + STATIC_ASSERT(borrowed_range == borrowed_range); // Validate take_view::size STATIC_ASSERT(CanMemberSize == CanSize); @@ -567,5 +568,18 @@ int main() { STATIC_ASSERT((instantiation_test(), true)); instantiation_test(); + { + // Validate a non-view borrowed range + constexpr span s{some_ints}; + STATIC_ASSERT(test_one(s, only_four_ints)); + test_one(s, only_four_ints); + + // Validate a view borrowed range + constexpr auto v = + views::iota(0ull, ranges::size(some_ints)) | views::transform([](auto i) { return some_ints[i]; }); + STATIC_ASSERT(test_one(v, only_four_ints)); + test_one(v, only_four_ints); + } + test_DevCom_1397309(); }