diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 55d3c520ba4..7d8b37f8c5c 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -4355,8 +4355,15 @@ namespace views::__adaptor namespace __detail { #if __cpp_lib_tuple_like // >= C++23 + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3797. elements_view insufficiently constrained template - concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>; + concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp> + && requires(_Tp __t) + { + { std::get<_Nm>(__t) } + -> convertible_to&>; + }; #else template concept __has_tuple_element = requires(_Tp __t) diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc index 5237d787e7b..d384cfd5adf 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc @@ -27,6 +27,22 @@ namespace ranges = std::ranges; namespace views = ranges::views; +template +concept can_elements = requires (Rg&& rg) +{ views::elements<0>(rg); }; + +static_assert( !can_elements<0, std::vector> ); +static_assert( can_elements<0, std::tuple[4]> ); +static_assert( can_elements<1, std::vector>> ); + +// Test LWG 3797. elements_view insufficiently constrained +using move_only_iter_range = __gnu_test::test_input_range_nocopy; +using move_only_iter_subrange = ranges::subrange< + ranges::iterator_t, + ranges::sentinel_t>; +static_assert( can_elements<0, std::vector>> ); +static_assert( !can_elements<0, std::vector> ); + void test01() {