diff --git a/libcxx/include/__ranges/all.h b/libcxx/include/__ranges/all.h index 5f9bf7e277ed75..181477419c8500 100644 --- a/libcxx/include/__ranges/all.h +++ b/libcxx/include/__ranges/all.h @@ -39,6 +39,7 @@ namespace __all { [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t)))) + -> decltype(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t))) { return _LIBCPP_AUTO_CAST(std::forward<_Tp>(__t)); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp index 0e3d5abb11edc3..4d4d1ebc0b226f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.all/all.pass.cpp @@ -49,6 +49,17 @@ struct CopyableView : std::ranges::view_base { static_assert(std::ranges::view>); static_assert(std::ranges::view>); +struct MoveOnlyView : std::ranges::view_base{ + MoveOnlyView() = default; + MoveOnlyView(const MoveOnlyView&) = delete; + MoveOnlyView& operator=(const MoveOnlyView&) = delete; + MoveOnlyView(MoveOnlyView&&) = default; + MoveOnlyView& operator=(MoveOnlyView&&) = default; + + int* begin() const; + int* end() const; +}; + struct Range { int start_; constexpr explicit Range(int start) noexcept : start_(start) {} @@ -139,6 +150,11 @@ constexpr bool test() { { static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); + + // `views::all(v)` is expression equivalent to `decay-copy(v)` if the decayed type + // of `v` models `view`. If `v` is an lvalue-reference to a move-only view, the + // expression should be ill-formed because `v` is not copyable + static_assert(!std::is_invocable_v); } // Test that std::views::all is a range adaptor